home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / unix / rcs.12 < prev    next >
Text File  |  1989-11-19  |  76KB  |  2,632 lines

  1. Path: xanth!samsung!usc!apple!sun-barr!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i227:  rcs - revision control system, Part12/14
  5. Message-ID: <128103@sun.Eng.Sun.COM>
  6. Date: 19 Nov 89 09:25:59 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2621
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: rsbx@cbmvax.commodore.com (Raymond S. Brand)
  12. Posting-number: Volume 89, Issue 227
  13. Archive-name: unix/rcs.12
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    rcs/rcs.rcsfiles/snoop.c,v
  24. #    rcs/rcs.rcsfiles/time.h,v
  25. #    rcs/rcs.rcsfiles/rcsfreeze.sh,v
  26. #    rcs/rcs.rcsfiles/amiga.c,v
  27. #    rcs/rcs.rcsfiles/stat.h,v
  28. #    rcs/rcs.rcsfiles/ci.c,v
  29. # This is archive 12 of a 14-part kit.
  30. # This archive created: Sun Nov 19 01:12:12 1989
  31. if `test ! -d rcs`
  32. then
  33.   mkdir rcs
  34.   echo "mkdir rcs"
  35. fi
  36. if `test ! -d rcs/rcs.rcsfiles`
  37. then
  38.   mkdir rcs/rcs.rcsfiles
  39.   echo "mkdir rcs/rcs.rcsfiles"
  40. fi
  41. echo "extracting rcs/rcs.rcsfiles/snoop.c,v"
  42. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/snoop.c,v
  43. Xhead     4.4;
  44. Xbranch   4.4.2;
  45. Xaccess   ;
  46. Xsymbols  amiga_rcs:4.4.2 cbmvax_source:4.4.1 uunet_june89_dist:4.4;
  47. Xlocks    ; strict;
  48. Xcomment  @ * @;
  49. X
  50. X
  51. X4.4
  52. Xdate     89.05.01.15.14.00;  author narten;  state Exp;
  53. Xbranches 4.4.1.1 4.4.2.1;
  54. Xnext     ;
  55. X
  56. X4.4.1.1
  57. Xdate     89.08.11.01.43.23;  author rsbx;  state Exp;
  58. Xbranches ;
  59. Xnext     ;
  60. X
  61. X4.4.2.1
  62. Xdate     89.10.13.19.19.37;  author rsbx;  state Exp;
  63. Xbranches ;
  64. Xnext     4.4.2.2;
  65. X
  66. X4.4.2.2
  67. Xdate     89.10.15.15.45.25;  author rsbx;  state Exp;
  68. Xbranches ;
  69. Xnext     ;
  70. X
  71. X
  72. Xdesc
  73. X@Logging of RCS commands co and ci.
  74. X@
  75. X
  76. X
  77. X
  78. X4.4
  79. Xlog
  80. X@checked in with -k by rsbx at 89.08.10.16.23.48.
  81. X@
  82. Xtext
  83. X@/*
  84. X *                     Logging of RCS commands co and ci
  85. X */
  86. X#ifndef lint
  87. X static char rcsid[]=
  88. X "$Header: /usr/src/local/bin/rcs/src/RCS/snoop.c,v 4.4 89/05/01 15:14:00 narten Exp $ Purdue CS";
  89. X#endif
  90. X/*******************************************************************
  91. X * This program appends argv[1] to the file SNOOPFILE.
  92. X * To avoid overlaps, it creates a lockfile with name lock in the same
  93. X * directory as SNOOPFILE. SNOOPFILE must be defined in the cc command. 
  94. X * Prints an error message if lockfile doesn't get deleted after
  95. X * MAXTRIES tries.
  96. X *******************************************************************
  97. X */
  98. X
  99. X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
  100. X * All rights reserved.
  101. X *
  102. X * Redistribution and use in source and binary forms are permitted
  103. X * provided that the above copyright notice and this paragraph are
  104. X * duplicated in all such forms and that any documentation,
  105. X * advertising materials, and other materials related to such
  106. X * distribution and use acknowledge that the software was developed
  107. X * by Walter Tichy.
  108. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  109. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  110. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  111. X *
  112. X * Report all problems and direct all questions to:
  113. X *   rcs-bugs@@cs.purdue.edu
  114. X * 
  115. X
  116. X
  117. X
  118. X
  119. X
  120. X
  121. X
  122. X*/
  123. X
  124. X
  125. X/* $Log:    snoop.c,v $
  126. X * Revision 4.4  89/05/01  15:14:00  narten
  127. X * changed copyright header to reflect current distribution rules
  128. X * 
  129. X * Revision 4.3  87/12/18  11:46:52  narten
  130. X * more lint cleanups (Guy Harris)
  131. X * 
  132. X * Revision 4.2  87/10/18  10:41:47  narten
  133. X * Changing version numbers. Changes relative to 1.1 actually relative to 
  134. X * 4.1
  135. X * 
  136. X * Revision 1.2  87/09/24  14:01:41  narten
  137. X * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  138. X * warnings)
  139. X * 
  140. X * Revision 1.1  84/01/23  14:50:49  kcs
  141. X * Initial revision
  142. X * 
  143. X * Revision 4.1  83/03/28  13:23:42  wft
  144. X * No change; just new revision number.
  145. X * 
  146. X * Revision 3.2  82/12/04  17:14:31  wft
  147. X * Added rcsbase.h, changed SNOOPDIR to SNOOPFILE, reintroduced
  148. X * error message in case of permanent locking.
  149. X * 
  150. X * Revision 3.1  82/10/18  21:22:03  wft
  151. X * Number of polls now 20, no error message if critical section can't
  152. X * be entered.
  153. X * 
  154. X * Revision 2.3  82/07/01  23:49:28  wft
  155. X * changed copyright notice only.
  156. X * 
  157. X * Revision 2.2  82/06/03  20:00:10  wft
  158. X * changed name from rcslog to snoop, replaced LOGDIR with SNOOPDIR.
  159. X * 
  160. X * Revision 2.1  82/05/06  17:55:54  wft
  161. X * Initial revision
  162. X *
  163. X */
  164. X
  165. X
  166. X#include "rcsbase.h"
  167. X#define fflsbuf _flsbuf
  168. X/* undo redefinition of putc in rcsbase.h */
  169. X
  170. Xchar  lockfname[NCPPN];
  171. XFILE * logfile;
  172. Xint lockfile;
  173. X
  174. X#define MAXTRIES 20
  175. X
  176. Xmain(argc,argv)
  177. Xint argc; char * argv[];
  178. X/* writes argv[1] to SNOOPFILE and appends a newline. Invoked as follows:
  179. X * rcslog logmessage
  180. X */
  181. X{       int tries;
  182. X        register char * lastslash, *sp;
  183. X
  184. X        VOID strcpy(lockfname,(char *) SNOOPFILE);
  185. X        lastslash = sp = lockfname;
  186. X        while (*sp) if (*sp++ =='/') lastslash=sp; /* points beyond / */
  187. X        VOID strcpy(lastslash,",lockfile");
  188. X        tries=0;
  189. X        while (((lockfile=creat(lockfname, 000)) == -1) && (tries<=MAXTRIES)) {
  190. X                tries++;
  191. X                sleep(5);
  192. X        }
  193. X        if (tries<=MAXTRIES) {
  194. X                VOID close(lockfile);
  195. X                if ((logfile=fopen(SNOOPFILE,"a")) ==NULL) {
  196. X                        VOID fprintf(stderr,"Can't open logfile %s\n",SNOOPFILE);
  197. X                } else {
  198. X                        VOID fputs(argv[1],logfile);
  199. X                        VOID putc('\n',logfile);
  200. X                        VOID fclose(logfile);
  201. X                }
  202. X                VOID unlink(lockfname);
  203. X        } else {
  204. X                VOID fprintf(stderr,"RCS logfile %s seems permanently locked.\n",SNOOPFILE);
  205. X                VOID fprintf(stderr,"Please alert system administrator\n");
  206. X        }
  207. X}
  208. X@
  209. X
  210. X
  211. X4.4.2.1
  212. Xlog
  213. X@Start of Amiga RCS port branch.
  214. X@
  215. Xtext
  216. X@d6 1
  217. Xa6 5
  218. X<<<<<<< snoop.c
  219. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS.cbmvax/snoop.c,v 4.4.1.1 89/08/11 01:43:23 rsbx Exp Locker: rsbx $ Purdue CS";
  220. X=======
  221. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/snoop.c,v 1.2 89/09/17 13:37:13 rick Exp $ Purdue CS";
  222. X>>>>>>> 1.2
  223. Xa43 11
  224. X<<<<<<< snoop.c
  225. X * Revision 4.4.1.1  89/08/11  01:43:23  rsbx
  226. X * Start of cbmvax RCS source branch.
  227. X=======
  228. X * Revision 1.2  89/09/17  13:37:13  rick
  229. X * Port to AmigaDos done by Rick Schaeffer (ricks@@iscuva.iscs.com)
  230. X * All changes done with conditional compile (#ifdef AMIGA).  This version
  231. X * compiles correctly with Lattice C version 5.02 or later.
  232. X>>>>>>> 1.2
  233. X * 
  234. X<<<<<<< snoop.c
  235. Xa44 3
  236. X * checked in with -k by rsbx at 89.08.10.16.23.48.
  237. X * 
  238. X * Revision 4.4  89/05/01  15:14:00  narten
  239. Xa45 4
  240. X=======
  241. X * Revision 1.2  88/09/03  15:13:53  rick
  242. X * Port to AmigaDos.  All done with conditional compiles
  243. X>>>>>>> 1.2
  244. X@
  245. X
  246. X
  247. X4.4.2.2
  248. Xlog
  249. X@Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
  250. Xsources I have here (and are later than the ones Rick used).
  251. X@
  252. Xtext
  253. X@d6 5
  254. Xa10 1
  255. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/snoop.c,v 4.4.2.1 89/10/13 19:19:37 rsbx Exp Locker: rsbx $ Purdue CS";
  256. Xd48 1
  257. Xa48 3
  258. X * Revision 4.4.2.1  89/10/13  19:19:37  rsbx
  259. X * Start of Amiga RCS port branch.
  260. X * 
  261. Xd51 6
  262. Xd58 1
  263. Xd64 4
  264. X@
  265. X
  266. X
  267. X4.4.1.1
  268. Xlog
  269. X@Start of cbmvax RCS source branch.
  270. X@
  271. Xtext
  272. X@d6 1
  273. Xa6 1
  274. X "$Header: /u/softeng/rsbx/rcs/rcs.uunet/src/RCS/snoop.c,v 4.4 89/05/01 15:14:00 narten Exp $ Purdue CS";
  275. Xa43 3
  276. X * Revision 4.4  89/05/01  15:14:00  narten
  277. X * checked in with -k by rsbx at 89.08.10.16.23.48.
  278. X * 
  279. X@
  280. SHAR_EOF
  281. echo "extracting rcs/rcs.rcsfiles/time.h,v"
  282. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/time.h,v
  283. Xhead     1.1;
  284. Xbranch   1.1.2;
  285. Xaccess   ;
  286. Xsymbols  amiga_rcs:1.1.2 cbmvax_source:1.1.1 uunet_june89_dist:1.1;
  287. Xlocks    ; strict;
  288. Xcomment  @ * @;
  289. X
  290. X
  291. X1.1
  292. Xdate     84.01.23.14.50.50;  author kcs;  state Exp;
  293. Xbranches 1.1.1.1 1.1.2.1;
  294. Xnext     ;
  295. X
  296. X1.1.1.1
  297. Xdate     89.08.11.01.43.25;  author rsbx;  state Exp;
  298. Xbranches ;
  299. Xnext     ;
  300. X
  301. X1.1.2.1
  302. Xdate     89.10.13.19.16.42;  author rsbx;  state Exp;
  303. Xbranches ;
  304. Xnext     ;
  305. X
  306. X
  307. Xdesc
  308. X@Structure for use by time manipulation subroutines.
  309. X@
  310. X
  311. X
  312. X
  313. X1.1
  314. Xlog
  315. X@Initial revision
  316. X@
  317. Xtext
  318. X@
  319. X/* Structure for use by time manipulating subroutines.
  320. X * The following library routines use it:
  321. X *    libc: ctime, localtime, gmtime, asctime
  322. X *    libcx: partime, maketime (may not be installed yet)
  323. X */
  324. X
  325. X#define TIMEID "$Id: time.h,v 1.1 84/01/23 14:50:50 kcs Exp $"
  326. X
  327. X/* $Log:    time.h,v $
  328. X * Revision 1.1  84/01/23  14:50:50  kcs
  329. X * Initial revision
  330. X * 
  331. X * Revision 1.1  82/05/06  11:34:29  wft
  332. X * Initial revision
  333. X * 
  334. X */
  335. X
  336. Xstruct tm {     /* See defines below for allowable ranges */
  337. X    int tm_sec;
  338. X    int tm_min;
  339. X    int tm_hour;
  340. X    int tm_mday;
  341. X    int tm_mon;
  342. X    int tm_year;
  343. X    int tm_wday;
  344. X    int tm_yday;
  345. X    int tm_isdst;
  346. X    int tm_zon;    /* NEW: mins westward of Greenwich */
  347. X    int tm_ampm;    /* NEW: 1 if AM, 2 if PM */
  348. X};
  349. X
  350. X#define LCLZONE (5*60)    /* Until V7 ftime(2) works, this defines local zone*/
  351. X#define TMNULL (-1)    /* Items not specified are given this value
  352. X             * in order to distinguish null specs from zero
  353. X             * specs.  This is only used by partime and
  354. X             * maketime. */
  355. X
  356. X    /* Indices into TM structure */
  357. X#define TM_SEC 0    /* 0-59            */
  358. X#define TM_MIN 1    /* 0-59            */
  359. X#define TM_HOUR 2    /* 0-23            */
  360. X#define TM_MDAY 3    /* 1-31            day of month */
  361. X#define TM_DAY TM_MDAY    /*  "            synonym      */
  362. X#define TM_MON 4    /* 0-11            */
  363. X#define TM_YEAR 5    /* (year-1900) (year)    */
  364. X#define TM_WDAY 6    /* 0-6            day of week (0 = Sunday) */
  365. X#define TM_YDAY 7    /* 0-365        day of year */
  366. X#define TM_ISDST 8    /* 0 Std, 1 DST        */
  367. X    /* New stuff */
  368. X#define TM_ZON 9    /* 0-(24*60) minutes west of Greenwich */
  369. X#define TM_AMPM 10    /* 1 AM, 2 PM        */
  370. X@
  371. X
  372. X
  373. X1.1.2.1
  374. Xlog
  375. X@Start of Amiga RCS port branch.
  376. X@
  377. Xtext
  378. X@d8 1
  379. Xa8 1
  380. X#define TIMEID "$Id: time.h,v 1.1.1.1 89/08/11 01:43:25 rsbx Exp Locker: rsbx $"
  381. Xa10 6
  382. X * Revision 1.1.1.1  89/08/11  01:43:25  rsbx
  383. X * Start of cbmvax RCS source branch.
  384. X * 
  385. X * Revision 1.1  84/01/23  14:50:50  kcs
  386. X * Initial revision
  387. X * 
  388. X@
  389. X
  390. X
  391. X1.1.1.1
  392. Xlog
  393. X@Start of cbmvax RCS source branch.
  394. X@
  395. Xtext
  396. X@a13 3
  397. X * Revision 1.1  84/01/23  14:50:50  kcs
  398. X * Initial revision
  399. X * 
  400. X@
  401. SHAR_EOF
  402. echo "extracting rcs/rcs.rcsfiles/rcsfreeze.sh,v"
  403. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/rcsfreeze.sh,v
  404. Xhead     1.1;
  405. Xbranch   1.1.2;
  406. Xaccess   ;
  407. Xsymbols  amiga_rcs:1.1.2 cbmvax_source:1.1.1 uunet_june89_dist:1.1;
  408. Xlocks    ; strict;
  409. Xcomment  @# @;
  410. X
  411. X
  412. X1.1
  413. Xdate     89.08.10.16.29.10;  author rsbx;  state Exp;
  414. Xbranches 1.1.1.1 1.1.2.1;
  415. Xnext     ;
  416. X
  417. X1.1.1.1
  418. Xdate     89.08.11.01.42.39;  author rsbx;  state Exp;
  419. Xbranches ;
  420. Xnext     ;
  421. X
  422. X1.1.2.1
  423. Xdate     89.10.13.19.20.11;  author rsbx;  state Exp;
  424. Xbranches ;
  425. Xnext     ;
  426. X
  427. X
  428. Xdesc
  429. X@RCS rcsfreeze operation.
  430. X@
  431. X
  432. X
  433. X
  434. X1.1
  435. Xlog
  436. X@Initial revision
  437. X@
  438. Xtext
  439. X@#! /bin/sh
  440. XPATH=/usr/local/bin:/bin:/usr/bin:/usr/ucb
  441. X#       'rcsfreeze' has the purpose of assigning a symbolic revision
  442. X#       number to a set of RCS files, which form a valid configuration.
  443. X#
  444. X#       The idea is to run rcsfreeze each time a new version is checked
  445. X#       in. A unique symbolic revision number (C_[number], where number
  446. X#       is increased each time rcsfreeze is run) is then assigned to the most
  447. X#       recent revision of each RCS file of the main trunk.
  448. X#
  449. X#       If the command is invoked with an argument, then this
  450. X#       argument is used as the symbolic name to freeze a configuration.
  451. X#       The unique identifier is still generated
  452. X#       and is listed in the log file but it will not appear as
  453. X#       part of the symbolic revision name in the actual RCS file.
  454. X#
  455. X#       A log message is requested from the user which is saved for future
  456. X#       references.
  457. X#
  458. X#       The shell script works only on all RCS files at one time.
  459. X#       It is important that all changed files are checked in (there are
  460. X#       no precautions against any error in this respect).
  461. X#       file names:
  462. X#       {RCS/}rcsfreeze.version         for the version number
  463. X#       {RCS/}rscfreeze.log             for the log messages, most recent
  464. X#                                       logmessage first.
  465. X
  466. Xprogname=`basename $0`
  467. XDATE=`date`
  468. X# Check whether we have an RCS subdirectory, so we can have the right
  469. X# prefix for our paths.
  470. Xif [ -d RCS ] ; then
  471. X    RCSDIR=RCS
  472. Xelse
  473. X    RCSDIR=.
  474. Xfi
  475. X
  476. X# Version number stuff, log message file
  477. XVERSIONFILE=$RCSDIR/.rcsfreeze.version
  478. XLOGFILE=$RCSDIR/.rcsfreeze.log
  479. Xif [ ! -r $VERSIONFILE ] ; then
  480. X# Initialize, rcsfreeze never run before in the current directory
  481. X    cat << EOF > $VERSIONFILE
  482. X0
  483. XEOF
  484. X    touch       $LOGFILE
  485. Xfi
  486. X
  487. X# Get Version number, increase it, write back to file.
  488. XVERSIONNUMBER=`cat $VERSIONFILE`
  489. XVERSIONNUMBER=`expr $VERSIONNUMBER + 1`
  490. X    cat << EOF > $VERSIONFILE
  491. X$VERSIONNUMBER
  492. XEOF
  493. X
  494. X# Symbolic Revision Number
  495. XSYMREV=C_$VERSIONNUMBER
  496. X# Allow the user to give a meaningful symbolic name to the revision.
  497. XSYMREVNAME=${1-$SYMREV}
  498. Xecho    "$progname: symbolic revision number computed: \"$SYMREV\""
  499. Xecho    "$progname: symbolic revision number used:     \"$SYMREVNAME\""
  500. Xecho    "$progname: the two differ only when $progname invoked with argument"
  501. X
  502. X# Stamp the logfile. Because we order the logfile the most recent
  503. X# first we will have to save everything right now in a temporary file.
  504. XTMPLOG=/tmp/rcsfreeze.$$.log.tmp
  505. Xecho "Version: $SYMREVNAME($SYMREV), Date: $DATE"     > $TMPLOG
  506. Xecho "-----------"                      >> $TMPLOG
  507. X# Now ask for a log message, continously add to the log file
  508. Xecho    "$progname: give log message, summarizing changes"
  509. Xecho    "       (terminate with ^D or single '.')"
  510. Xwhile read MESS ; do
  511. X    if [ "$MESS" = '.' ] ; then break ; fi
  512. X    echo "  $MESS"      >> $TMPLOG
  513. Xdone
  514. Xecho "-----------"                      >> $TMPLOG
  515. Xecho                                    >> $TMPLOG
  516. X
  517. X# combine old and new logfiles
  518. XTMPLOG2=$TMPLOG.2
  519. Xcat $TMPLOG $LOGFILE >  $TMPLOG2
  520. Xcp $TMPLOG2     $LOGFILE
  521. Xrm -f  $TMPLOG $TMPLOG2
  522. X
  523. X# Now the real work begins by assigning a symbolic revision number
  524. X# to each rcs file. Take the most recent version of the main trunk.
  525. X
  526. Xfor FILE in $RCSDIR/* ; do
  527. X#   get the revision number of the most recent revision
  528. X    REV=`rlog -h -d"$DATE" $FILE | fgrep 'head:' | awk ' { print $2 } ' `
  529. X    echo        "$progname: file name: \"$FILE\", Revision Number: $REV"
  530. X#   assign symbolic name to it.
  531. X    rcs -q -n$SYMREVNAME:$REV $FILE
  532. Xdone
  533. X@
  534. X
  535. X
  536. X1.1.2.1
  537. Xlog
  538. X@Start of Amiga RCS port branch.
  539. X@
  540. Xtext
  541. X@@
  542. X
  543. X
  544. X1.1.1.1
  545. Xlog
  546. X@Start of cbmvax RCS source branch.
  547. X@
  548. Xtext
  549. X@@
  550. SHAR_EOF
  551. echo "extracting rcs/rcs.rcsfiles/amiga.c,v"
  552. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/amiga.c,v
  553. Xhead     1.11;
  554. Xbranch   1;
  555. Xaccess   ;
  556. Xsymbols  amiga_rcs:1;
  557. Xlocks    ; strict;
  558. Xcomment  @ * @;
  559. X
  560. X
  561. X1.11
  562. Xdate     89.11.03.20.20.33;  author rsbx;  state Exp;
  563. Xbranches ;
  564. Xnext     1.10;
  565. X
  566. X1.10
  567. Xdate     89.11.02.23.27.51;  author rsbx;  state Exp;
  568. Xbranches ;
  569. Xnext     1.9;
  570. X
  571. X1.9
  572. Xdate     89.11.01.14.43.57;  author rsbx;  state Exp;
  573. Xbranches ;
  574. Xnext     1.8;
  575. X
  576. X1.8
  577. Xdate     89.10.29.14.50.07;  author rsbx;  state Exp;
  578. Xbranches ;
  579. Xnext     1.7;
  580. X
  581. X1.7
  582. Xdate     89.10.29.14.23.50;  author rsbx;  state Exp;
  583. Xbranches ;
  584. Xnext     1.6;
  585. X
  586. X1.6
  587. Xdate     89.10.17.18.38.23;  author rsbx;  state Exp;
  588. Xbranches ;
  589. Xnext     1.5;
  590. X
  591. X1.5
  592. Xdate     89.10.17.15.03.46;  author rsbx;  state Exp;
  593. Xbranches ;
  594. Xnext     1.4;
  595. X
  596. X1.4
  597. Xdate     89.10.16.15.07.49;  author rsbx;  state Exp;
  598. Xbranches ;
  599. Xnext     1.3;
  600. X
  601. X1.3
  602. Xdate     89.10.15.18.26.30;  author rsbx;  state Exp;
  603. Xbranches ;
  604. Xnext     1.2;
  605. X
  606. X1.2
  607. Xdate     89.10.15.15.38.36;  author rsbx;  state Exp;
  608. Xbranches ;
  609. Xnext     1.1;
  610. X
  611. X1.1
  612. Xdate     89.10.13.19.26.17;  author rsbx;  state Exp;
  613. Xbranches ;
  614. Xnext     ;
  615. X
  616. X
  617. Xdesc
  618. X@Glue routines for Amiga RCS port.
  619. X@
  620. X
  621. X
  622. X1.11
  623. Xlog
  624. X@Changes to run() and run_back() for use with LaunchChild().
  625. X@
  626. Xtext
  627. X@/*
  628. X *  Glue functions for the RCS system needed for the Amiga
  629. X */
  630. X
  631. X#ifndef lint
  632. Xstatic char rcsid[]=
  633. X"$Id: amiga.c,v 1.10 89/11/02 23:27:51 rsbx Exp $";
  634. X#endif
  635. X
  636. X#include <stdio.h>
  637. X#include <errno.h>
  638. X#include <proto/exec.h>
  639. X#include <exec/tasks.h>
  640. X#include <ios1.h>
  641. X#include <dos.h>
  642. X#include <fcntl.h>
  643. X#include <exec/exec.h>
  644. X#include <libraries/dosextens.h>
  645. X#include "stat.h"
  646. X#include <stdarg.h>
  647. X#include <rsbx/childtasking.h>
  648. X
  649. X
  650. Xextern char *talloc(int size);
  651. Xextern char *fnamepart(char *name);
  652. X
  653. Xextern char *RCSfilename;
  654. X
  655. X/*
  656. X * this should be NCPPN but I can't include rcsbase.h without getting
  657. X * 'redefinition of "VOID"' message because <exec/types.h> thinks that
  658. X * it owns VOID and the rest of the world can goto hell.
  659. X */
  660. X#define PATHSIZE 1024
  661. X
  662. X
  663. Xumask(mode)
  664. X{
  665. X    return mode;
  666. X}
  667. X
  668. Xint stat(name,buf)
  669. Xchar    *name;
  670. Xstruct stat *buf;
  671. X{
  672. X    long l;
  673. X    struct FileInfoBlock *fp,*malloc();
  674. X
  675. X    if ((l=Lock(name, ACCESS_READ)) == 0)
  676. X        return(-1);
  677. X    fp = malloc(sizeof(struct FileInfoBlock));
  678. X    Examine(l, fp);
  679. X    buf->st_attr = ~fp->fib_Protection;
  680. X    buf->st_size = fp->fib_Size;
  681. X    buf->st_type = fp->fib_DirEntryType;
  682. X    UnLock(l);
  683. X    free(fp);
  684. X    buf->st_mtime = getft(name);
  685. X    return 0;
  686. X}
  687. X
  688. Xisatty(fd)
  689. Xint        fd;
  690. X{
  691. X    long IsInteractive();
  692. X    struct UFB    *ufb;
  693. X
  694. X    ufb = chkufb(fd);
  695. X    if (ufb == NULL)
  696. X        return(-1);
  697. X    return(IsInteractive(ufb->ufbfh) != 0);
  698. X}
  699. X
  700. X
  701. Xint run_back(BPTR infh, BPTR outfh, char ** inoutargs)
  702. X{
  703. X    struct LAUNCHENV env = { 0,0,0,0,0,0,0 };
  704. X    struct Task *task = FindTask(0);
  705. X
  706. X    env.priority = task->tc_Node.ln_Pri;
  707. X    env.stack = (char *)task->tc_SPUpper - (char *)task->tc_SPLower;
  708. X    env.std_in = infh;
  709. X    env.std_out =  outfh;
  710. X
  711. X    return (int)LaunchChildv(&env, *inoutargs, inoutargs);
  712. X}
  713. X
  714. X
  715. X#define CARGSMAX 20
  716. X
  717. X/*
  718. X * Run a command.
  719. X * The first two arguments are the input and output files (if nonnil);
  720. X * the rest specify the command and its arguments.
  721. X */
  722. Xint run(char *arg0, char *arg1, ...)
  723. X{
  724. X    va_list ap;
  725. X    int pid, status;
  726. X    char *rgargs[CARGSMAX];
  727. X    register int i;
  728. X    BPTR Binfh, Boutfh;
  729. X
  730. X    va_start(ap, arg1);
  731. X    Binfh = Boutfh = 0;
  732. X    status = -1;
  733. X
  734. X    if (arg0)
  735. X        {
  736. X        if (!(Binfh = (BPTR)Open(arg0, MODE_OLDFILE)))
  737. X            {
  738. X            return -1;
  739. X            }
  740. X        }
  741. X
  742. X    if (arg1)
  743. X        {
  744. X        if (!(Boutfh = (BPTR)Open(arg1, MODE_NEWFILE)))
  745. X            {
  746. X            if (Binfh)
  747. X                {
  748. X                Close(Binfh);
  749. X                }
  750. X            return -1;
  751. X            }
  752. X        }
  753. X
  754. X    for (i=0; i< CARGSMAX; i++) {
  755. X        rgargs[i] = va_arg(ap, char *);
  756. X        if (rgargs[i] == NULL)
  757. X        break;
  758. X    }
  759. X    va_end(ap);
  760. X    if (pid = run_back(Binfh, Boutfh, rgargs))
  761. X        {
  762. X        if (!WaitChild((struct ChildNode *)pid, &status))
  763. X            {
  764. X            status = -1;
  765. X            }
  766. X        }
  767. X
  768. X    if (Binfh)
  769. X        {
  770. X        Close(Binfh);
  771. X        }
  772. X    if (Boutfh)
  773. X        {
  774. X        Close(Boutfh);
  775. X        }
  776. X
  777. X    return status;
  778. X}
  779. X
  780. X
  781. X
  782. Xstatic char *path = "ENV:";
  783. X
  784. Xchar *getenv(char *name)
  785. X    {
  786. X    char *fullname, *buff;
  787. X    FILE *f;
  788. X    int len;
  789. X    struct stat varstats;
  790. X
  791. X    if (!(len = strlen(name)))
  792. X        {
  793. X        return NULL;
  794. X        }
  795. X
  796. X    fullname = talloc(strlen(path)+len+1);
  797. X    sprintf(fullname, "%s%s", path, name);
  798. X
  799. X    if (stat(fullname, &varstats))
  800. X        {
  801. X        free(fullname);
  802. X        return NULL;
  803. X        }
  804. X
  805. X    buff = talloc((len = varstats.st_size)+1);
  806. X    if (!(f = fopen(fullname, "r")))
  807. X        {
  808. X        free(buff);
  809. X        free(fullname);
  810. X        return NULL;
  811. X        }
  812. X
  813. X    if (!(len = fread(buff, 1, len, f)))
  814. X        {
  815. X        fclose(f);
  816. X        free(buff);
  817. X        free(fullname);
  818. X        return NULL;
  819. X        }
  820. X
  821. X    *(buff+len) = '\0';
  822. X    fclose(f);
  823. X    free(fullname);
  824. X    return buff;
  825. X    }
  826. X
  827. X
  828. Xchar * getfullRCSname( void )
  829. X/*
  830. X * Function: returns a pointer to the full path name of the RCS file.
  831. X */
  832. X    {
  833. X    static char pathbuf[PATHSIZE];
  834. X    static char namebuf[PATHSIZE];
  835. X
  836. X    char *namestart;
  837. X    BPTR lock, plock;
  838. X    char c;
  839. X    int len;
  840. X
  841. X    strcpy(pathbuf, RCSfilename);
  842. X    namestart = fnamepart(pathbuf);
  843. X    c = *namestart;
  844. X    *namestart = '\0';
  845. X
  846. X    if (!(lock = Lock(pathbuf, ACCESS_READ)))
  847. X        {
  848. X        faterror("Can't build full RCS file name");
  849. X        }
  850. X
  851. X    if (getpath(lock, namebuf))
  852. X        {
  853. X        UnLock(lock);
  854. X        faterror("Can't build full RCS file name");
  855. X        }
  856. X
  857. X    *namestart = c;
  858. X    len = strlen(namebuf);
  859. X
  860. X    if (plock = ParentDir(lock))
  861. X        {
  862. X        UnLock(plock);
  863. X        c = '/';
  864. X        }
  865. X    else
  866. X        {
  867. X        c = ':';
  868. X        }
  869. X
  870. X    UnLock(lock);
  871. X    namebuf[len] = c;
  872. X    namebuf[len+1] = '\0';
  873. X
  874. X    return strcat(namebuf, namestart);
  875. X    }
  876. X@
  877. X
  878. X
  879. X1.10
  880. Xlog
  881. X@Changed to use LaunchChild() and WaitChild() instead of forkv() and
  882. Xwait().
  883. X@
  884. Xtext
  885. X@d7 1
  886. Xa7 1
  887. X"$Id: amiga.c,v 1.9 89/11/01 14:43:57 rsbx Exp $";
  888. Xd106 1
  889. Xd120 1
  890. Xa120 1
  891. X            if (arg0)
  892. Xd134 1
  893. Xa134 1
  894. X    if (!(pid = run_back(Binfh, Boutfh, rgargs)))
  895. Xd136 4
  896. Xa139 3
  897. X        Close(Binfh);
  898. X        Close(Boutfh);
  899. X        return -1;
  900. Xd142 1
  901. Xa142 1
  902. X    if (!WaitChild((struct ChildNode *)pid, &status))
  903. Xd144 5
  904. Xa148 1
  905. X        return -1;
  906. X@
  907. X
  908. X
  909. X1.9
  910. Xlog
  911. X@Removed private chmod() and changed stat() to make protection bit
  912. Xmanipulation less insane.
  913. X@
  914. Xtext
  915. X@d7 1
  916. Xa7 1
  917. X"$Id: amiga.c,v 1.8 89/10/29 14:50:07 rsbx Exp $";
  918. Xd21 1
  919. Xd23 1
  920. Xd75 1
  921. Xa75 1
  922. Xint run_back(BPTR infh, BPTR outfh, char ** inoutargs, struct ProcID *child)
  923. Xd77 2
  924. Xa78 1
  925. X    struct FORKENV env = { 0,32768,0,0,0,NULL };
  926. Xd80 2
  927. Xa81 1
  928. X    env.priority = ((struct Task *)FindTask(NULL))->tc_Node.ln_Pri;
  929. Xd85 1
  930. Xa85 1
  931. X    return forkv(*inoutargs,inoutargs,&env,child);
  932. Xd99 1
  933. Xa99 1
  934. X    int pid;
  935. Xa102 1
  936. X    struct ProcID child;
  937. Xd133 1
  938. Xa133 1
  939. X    if (run_back(Binfh, Boutfh, rgargs, &child) != 0)
  940. Xd140 4
  941. Xa143 1
  942. X    pid = wait(&child);
  943. Xd145 1
  944. Xa145 1
  945. X    return pid;
  946. X@
  947. X
  948. X
  949. X1.8
  950. Xlog
  951. X@Added rcsid string.
  952. X@
  953. Xtext
  954. X@d7 1
  955. Xa7 1
  956. X"$Id$";
  957. Xa39 19
  958. X/*
  959. X** This function is used in place of the lattice library function of
  960. X** the same name.  It handles all modes, not just "rwed".
  961. X*/
  962. Xchmod(name,mode)
  963. Xchar    *name;
  964. Xint    mode;
  965. X{
  966. X    long    amigamode;
  967. X    int    success;
  968. X
  969. X    amigamode = mode;
  970. X    success = SetProtection(name,amigamode);
  971. X    if (success)
  972. X        return(0);
  973. X    errno = ENOENT;
  974. X    return(-1);
  975. X}
  976. X
  977. Xd51 1
  978. Xa51 1
  979. X    buf->st_attr = fp->fib_Protection;
  980. X@
  981. X
  982. X
  983. X1.7
  984. Xlog
  985. X@Changed run() to not close the stdin and stdout files used by a child. This
  986. Xis because my forkl/forkv function will close them for you.
  987. X@
  988. Xtext
  989. X@d2 7
  990. Xa8 2
  991. X**  Glue functions for the RCS system needed for the Amiga
  992. X*/
  993. X@
  994. X
  995. X
  996. X1.6
  997. Xlog
  998. X@getfullRCSname() fixed up.
  999. X@
  1000. Xtext
  1001. X@d109 1
  1002. Xa109 1
  1003. X    int infh, outfh, pid;
  1004. Xa116 1
  1005. X    infh = outfh = 0;
  1006. Xd120 4
  1007. Xa123 2
  1008. X        infh = open(arg0, O_RDONLY, S_IREAD|S_IWRITE|S_IDELETE);
  1009. X        Binfh = (BPTR)(chkufb(infh)->ufbfh);
  1010. Xd128 8
  1011. Xa135 2
  1012. X        outfh = creat(arg1, S_IREAD|S_IWRITE|S_IDELETE);
  1013. X        Boutfh = (BPTR)(chkufb(outfh)->ufbfh);
  1014. Xd144 1
  1015. Xa144 2
  1016. X    pid = run_back(Binfh, Boutfh, rgargs, &child);
  1017. X    if (pid < 0)
  1018. Xd146 3
  1019. Xa148 1
  1020. X        return pid;
  1021. Xa151 9
  1022. X
  1023. X    if (infh)
  1024. X        {
  1025. X        close(infh);
  1026. X        }
  1027. X    if (outfh)
  1028. X        {
  1029. X        close(outfh);
  1030. X        }
  1031. X@
  1032. X
  1033. X
  1034. X1.5
  1035. Xlog
  1036. X@Yet more changes to getcaller().
  1037. X@
  1038. Xtext
  1039. X@d18 1
  1040. Xd20 10
  1041. Xd202 50
  1042. X@
  1043. X
  1044. X
  1045. X1.4
  1046. Xlog
  1047. X@run() move from rcsutil.c to amiga.c and made to work.
  1048. X@
  1049. Xtext
  1050. X@d17 1
  1051. Xd145 47
  1052. X@
  1053. X
  1054. X
  1055. X1.3
  1056. Xlog
  1057. X@stat() made more unix compatible.
  1058. X@
  1059. Xtext
  1060. X@d15 1
  1061. Xd17 1
  1062. Xd74 2
  1063. Xa75 1
  1064. Xint run_back(char ** inoutargs)
  1065. Xa76 1
  1066. X    struct ProcID child;
  1067. Xa77 1
  1068. X    int infh, outfh, retval;
  1069. Xd79 3
  1070. Xa81 2
  1071. X#ifdef DEBUG
  1072. X    char **args = inoutargs;
  1073. Xd83 2
  1074. Xa84 26
  1075. X    fprintf(stderr,"runback: ");
  1076. X    if (*args)
  1077. X        {
  1078. X        fprintf(stderr,"%%%s%%  ",*args);
  1079. X        }
  1080. X    else
  1081. X        {
  1082. X        fprintf(stderr,"NULL  ");
  1083. X        }
  1084. X    args++;
  1085. X    if (*args)
  1086. X        {
  1087. X        fprintf(stderr,"%%%s%%  ",*args);
  1088. X        }
  1089. X    else
  1090. X        {
  1091. X        fprintf(stderr,"NULL  ");
  1092. X        }
  1093. X    args++;
  1094. X    while (*args)
  1095. X        {
  1096. X        fprintf(stderr,"%%%s%%  ",*args++);
  1097. X        }
  1098. X    fprintf(stderr,"\n--------------------------------------\n");
  1099. X    fflush(stderr);
  1100. X#endif
  1101. Xa85 1
  1102. X    env.priority = ((struct Task *)FindTask(NULL))->tc_Node.ln_Pri;
  1103. Xd87 21
  1104. Xa107 1
  1105. X    if (inoutargs[0])
  1106. Xd109 2
  1107. Xa110 2
  1108. X        infh = open(inoutargs[0], O_RDONLY, S_IREAD|S_IWRITE|S_IDELETE);
  1109. X        env.std_in = (BPTR)(chkufb(infh)->ufbfh);
  1110. Xd113 1
  1111. Xa113 1
  1112. X    if (inoutargs[1])
  1113. Xd115 2
  1114. Xa116 2
  1115. X        outfh = creat(inoutargs[1], S_IREAD|S_IWRITE|S_IDELETE);
  1116. X        env.std_out = (BPTR)(chkufb(infh)->ufbfh);
  1117. Xd119 8
  1118. Xa126 1
  1119. X    if ((forkv(inoutargs[2],&inoutargs[2],&env,&child)) != 0)
  1120. Xd128 1
  1121. Xa128 1
  1122. X        retval = -1;
  1123. Xa129 4
  1124. X    else
  1125. X        {
  1126. X        retval = wait(&child);
  1127. X        }
  1128. Xd131 2
  1129. Xd142 1
  1130. Xa142 1
  1131. X    return(retval);
  1132. X@
  1133. X
  1134. X
  1135. X1.2
  1136. Xlog
  1137. X@Removed run_back() from rcsutil.c and put it here since its rather
  1138. Xsystem dependant
  1139. X@
  1140. Xtext
  1141. X@d5 1
  1142. Xd40 1
  1143. Xa40 1
  1144. Xstat(name,buf)
  1145. Xd57 1
  1146. Xd77 30
  1147. X@
  1148. X
  1149. X
  1150. X1.1
  1151. Xlog
  1152. X@Initial revision
  1153. X@
  1154. Xtext
  1155. X@d6 3
  1156. Xd10 1
  1157. Xa10 1
  1158. X#include <ios1.h>
  1159. Xd26 1
  1160. Xa26 1
  1161. Xint        mode;
  1162. Xd28 2
  1163. Xa29 2
  1164. X    long        amigamode;
  1165. X    int            success;
  1166. Xd52 1
  1167. Xd70 40
  1168. X@
  1169. SHAR_EOF
  1170. echo "extracting rcs/rcs.rcsfiles/stat.h,v"
  1171. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/stat.h,v
  1172. Xhead     1.2;
  1173. Xbranch   1;
  1174. Xaccess   ;
  1175. Xsymbols  amiga_rcs:1;
  1176. Xlocks    ; strict;
  1177. Xcomment  @ * @;
  1178. X
  1179. X
  1180. X1.2
  1181. Xdate     89.10.15.15.45.30;  author rsbx;  state Exp;
  1182. Xbranches ;
  1183. Xnext     1.1;
  1184. X
  1185. X1.1
  1186. Xdate     89.10.13.19.26.38;  author rsbx;  state Exp;
  1187. Xbranches ;
  1188. Xnext     ;
  1189. X
  1190. X
  1191. Xdesc
  1192. X@Part of Amiga RCS port glue.
  1193. X@
  1194. X
  1195. X
  1196. X1.2
  1197. Xlog
  1198. X@Added new field for file type.
  1199. X@
  1200. Xtext
  1201. X@#include <fcntl.h>
  1202. X
  1203. Xstruct stat {
  1204. X    long st_attr;
  1205. X    long st_mtime;
  1206. X    long st_size;
  1207. X    long st_type;
  1208. X};
  1209. X@
  1210. X
  1211. X
  1212. X1.1
  1213. Xlog
  1214. X@Initial revision
  1215. X@
  1216. Xtext
  1217. X@d4 1
  1218. Xa4 1
  1219. X    char st_attr;
  1220. Xd7 1
  1221. X@
  1222. SHAR_EOF
  1223. echo "extracting rcs/rcs.rcsfiles/ci.c,v"
  1224. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/ci.c,v
  1225. Xhead     4.9;
  1226. Xbranch   4.9.2;
  1227. Xaccess   ;
  1228. Xsymbols  amiga_rcs:4.9.2 cbmvax_source:4.9.1 uunet_june89_dist:4.9;
  1229. Xlocks    ; strict;
  1230. Xcomment  @ * @;
  1231. X
  1232. X
  1233. X4.9
  1234. Xdate     89.05.01.15.10.54;  author narten;  state Exp;
  1235. Xbranches 4.9.1.1 4.9.2.1;
  1236. Xnext     ;
  1237. X
  1238. X4.9.1.1
  1239. Xdate     89.08.11.01.41.27;  author rsbx;  state Exp;
  1240. Xbranches ;
  1241. Xnext     ;
  1242. X
  1243. X4.9.2.1
  1244. Xdate     89.10.13.19.17.07;  author rsbx;  state Exp;
  1245. Xbranches ;
  1246. Xnext     4.9.2.2;
  1247. X
  1248. X4.9.2.2
  1249. Xdate     89.10.15.15.40.32;  author rsbx;  state Exp;
  1250. Xbranches ;
  1251. Xnext     4.9.2.3;
  1252. X
  1253. X4.9.2.3
  1254. Xdate     89.10.15.18.26.56;  author rsbx;  state Exp;
  1255. Xbranches ;
  1256. Xnext     4.9.2.4;
  1257. X
  1258. X4.9.2.4
  1259. Xdate     89.10.30.13.36.06;  author rsbx;  state Exp;
  1260. Xbranches ;
  1261. Xnext     4.9.2.5;
  1262. X
  1263. X4.9.2.5
  1264. Xdate     89.11.01.14.40.05;  author rsbx;  state Exp;
  1265. Xbranches ;
  1266. Xnext     4.9.2.6;
  1267. X
  1268. X4.9.2.6
  1269. Xdate     89.11.09.21.28.00;  author rsbx;  state Exp;
  1270. Xbranches ;
  1271. Xnext     4.9.2.7;
  1272. X
  1273. X4.9.2.7
  1274. Xdate     89.11.12.15.05.20;  author rsbx;  state Exp;
  1275. Xbranches ;
  1276. Xnext     ;
  1277. X
  1278. X
  1279. Xdesc
  1280. X@RCS checkin operation.
  1281. X@
  1282. X
  1283. X
  1284. X
  1285. X4.9
  1286. Xlog
  1287. X@checked in with -k by rsbx at 89.08.10.16.00.43.
  1288. X@
  1289. Xtext
  1290. X@/* Copyright (C) 1982, 1988, 1989 Walter Tichy
  1291. X * All rights reserved.
  1292. X *
  1293. X * Redistribution and use in source and binary forms are permitted
  1294. X * provided that the above copyright notice and this paragraph are
  1295. X * duplicated in all such forms and that any documentation,
  1296. X * advertising materials, and other materials related to such
  1297. X * distribution and use acknowledge that the software was developed
  1298. X * by Walter Tichy.
  1299. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1300. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1301. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1302. X *
  1303. X * Report all problems and direct all questions to:
  1304. X *   rcs-bugs@@cs.purdue.edu
  1305. X * 
  1306. X
  1307. X
  1308. X
  1309. X
  1310. X
  1311. X
  1312. X
  1313. X*/
  1314. X
  1315. X/*
  1316. X *                     RCS checkin operation
  1317. X */
  1318. X#ifndef lint
  1319. X static char rcsid[]=
  1320. X "$Header: /usr/src/local/bin/rcs/src/RCS/ci.c,v 4.9 89/05/01 15:10:54 narten Exp $ Purdue CS";
  1321. X#endif
  1322. X/*******************************************************************
  1323. X *                       check revisions into RCS files
  1324. X *******************************************************************
  1325. X */
  1326. X
  1327. X
  1328. X
  1329. X/* $Log:    ci.c,v $
  1330. X * Revision 4.9  89/05/01  15:10:54  narten
  1331. X * changed copyright header to reflect current distribution rules
  1332. X * 
  1333. X * Revision 4.8  88/11/08  13:38:23  narten
  1334. X * changes from root@@seismo.CSS.GOV (Super User)
  1335. X * -d with no arguments uses the mod time of the file it is checking in
  1336. X * 
  1337. X * Revision 4.7  88/11/08  10:59:04  narten
  1338. X * changes from eggert
  1339. X * 
  1340. X * Revision 4.7  88/08/09  19:12:07  eggert
  1341. X * Make sure workfile is a regular file; use its mode if RCSfile doesn't have one.
  1342. X * Use execv(), not system(); allow cc -R; remove lint.
  1343. X * isatty(fileno(stdin)) -> ttystdin()
  1344. X * 
  1345. X * Revision 4.6  87/12/18  11:34:41  narten
  1346. X * lint cleanups (from Guy Harris)
  1347. X * 
  1348. X * Revision 4.5  87/10/18  10:18:48  narten
  1349. X * Updating version numbers. Changes relative to revision 1.1 are actually
  1350. X * relative to 4.3
  1351. X * 
  1352. X * Revision 1.3  87/09/24  13:57:19  narten
  1353. X * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  1354. X * warnings)
  1355. X * 
  1356. X * Revision 1.2  87/03/27  14:21:33  jenkins
  1357. X * Port to suns
  1358. X * 
  1359. X * Revision 1.1  84/01/23  14:49:54  kcs
  1360. X * Initial revision
  1361. X * 
  1362. X * Revision 4.3  83/12/15  12:28:54  wft
  1363. X * ci -u and ci -l now set mode of working file properly.
  1364. X * 
  1365. X * Revision 4.2  83/12/05  13:40:54  wft
  1366. X * Merged with 3.9.1.1: added calls to clearerr(stdin).
  1367. X * made rewriteflag external.
  1368. X * 
  1369. X * Revision 4.1  83/05/10  17:03:06  wft
  1370. X * Added option -d and -w, and updated assingment of date, etc. to new delta.
  1371. X * Added handling of default branches.
  1372. X * Option -k generates std. log message; fixed undef. pointer in reading of log.
  1373. X * Replaced getlock() with findlock(), link--unlink with rename(),
  1374. X * getpwuid() with getcaller().
  1375. X * Moved all revision number generation to new routine addelta().
  1376. X * Removed calls to stat(); now done by pairfilenames().
  1377. X * Changed most calls to catchints() with restoreints().
  1378. X * Directed all interactive messages to stderr.
  1379. X * 
  1380. X * Revision 3.9.1.1  83/10/19  04:21:03  lepreau
  1381. X * Added clearerr(stdin) to getlogmsg() for re-reading stdin.
  1382. X * 
  1383. X * Revision 3.9  83/02/15  15:25:44  wft
  1384. X * 4.2 prerelease
  1385. X * 
  1386. X * Revision 3.9  83/02/15  15:25:44  wft
  1387. X * Added call to fastcopy() to copy remainder of RCS file.
  1388. X *
  1389. X * Revision 3.8  83/01/14  15:34:05  wft
  1390. X * Added ignoring of interrupts while new RCS file is renamed;
  1391. X * Avoids deletion of RCS files by interrupts.
  1392. X *
  1393. X * Revision 3.7  82/12/10  16:09:20  wft
  1394. X * Corrected checking of return code from diff.
  1395. X *
  1396. X * Revision 3.6  82/12/08  21:34:49  wft
  1397. X * Using DATEFORM to prepare date of checked-in revision;
  1398. X * Fixed return from addbranch().
  1399. X *
  1400. X * Revision 3.5  82/12/04  18:32:42  wft
  1401. X * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE. Updated
  1402. X * field lockedby in removelock(), moved getlogmsg() before calling diff.
  1403. X *
  1404. X * Revision 3.4  82/12/02  13:27:13  wft
  1405. X * added option -k.
  1406. X *
  1407. X * Revision 3.3  82/11/28  20:53:31  wft
  1408. X * Added mustcheckin() to check for redundant checkins.
  1409. X * Added xpandfile() to do keyword expansion for -u and -l;
  1410. X * -m appends linefeed to log message if necessary.
  1411. X * getlogmsg() suppresses prompt if stdin is not a terminal.
  1412. X * Replaced keeplock with lockflag, fclose() with ffclose(),
  1413. X * %02d with %.2d, getlogin() with getpwuid().
  1414. X *
  1415. X * Revision 3.2  82/10/18  20:57:23  wft
  1416. X * An RCS file inherits its mode during the first ci from the working file,
  1417. X * otherwise it stays the same, except that write permission is removed.
  1418. X * Fixed ci -l, added ci -u (both do an implicit co after the ci).
  1419. X * Fixed call to getlogin(), added call to getfullRCSname(), added check
  1420. X * for write error.
  1421. X * Changed conflicting identifiers.
  1422. X *
  1423. X * Revision 3.1  82/10/13  16:04:59  wft
  1424. X * fixed type of variables receiving from getc() (char -> int).
  1425. X * added include file dbm.h for getting BYTESIZ. This is used
  1426. X * to check the return code from diff portably.
  1427. X */
  1428. X
  1429. X#include "rcsbase.h"
  1430. X#ifndef lint
  1431. Xstatic char rcsbaseid[] = RCSBASE;
  1432. X#endif
  1433. X#include <sys/types.h>
  1434. X#include <sys/stat.h>
  1435. X#include "time.h"
  1436. X
  1437. Xextern int    rename();                /*rename files                       */
  1438. Xextern char * getcaller();             /*login of caller                    */
  1439. Xextern struct hshentry * genrevs();    /*generate delta numbers             */
  1440. Xextern quietflag;                      /*suppresses diagnostics if true     */
  1441. Xextern int  nerror;                    /*counter for errors                 */
  1442. Xextern char * buildrevision();         /*constructs desired revision        */
  1443. Xextern char * checkid();               /*check identifiers                  */
  1444. Xextern int    partime();               /*parse free-format date/time        */
  1445. Xextern long   maketime();              /*convert parsed time to unix time.  */
  1446. Xextern long   time();                  /*get date and time                  */
  1447. Xextern struct tm * localtime();        /*convert unixtime into tm-structure */
  1448. Xextern char * getdate();               /*formates current date  (forward)   */
  1449. Xextern char * mktempfile();            /*temporary file name generator      */
  1450. Xextern struct lock * addlock();        /*adds a new lock                    */
  1451. Xextern char * getlogmsg();             /*obtains log message; forward       */
  1452. Xextern struct hshentry * removelock(); /*finds a caller's lock  (forward)   */
  1453. Xextern struct hshentry * findlock();   /*finds a lock                       */
  1454. Xextern char * xpandfile();             /*perform keyword expansion; forward */
  1455. X
  1456. Xextern char prevauthor[];
  1457. Xextern char prevdate[];
  1458. Xextern char prevrev[];
  1459. Xextern char prevstate [];
  1460. Xextern FILE * finptr;                  /* RCS input file                    */
  1461. Xextern FILE * frewrite;                /* new RCS file                      */
  1462. Xextern int    rewriteflag;             /* indicates whether input should be */
  1463. X                       /* echoed to frewrite                */
  1464. X
  1465. Xchar * newRCSfilename, * diffilename;
  1466. Xchar * RCSfilename,*workfilename,*expfilename,*newworkfilename;
  1467. Xextern struct stat RCSstat, workstat; /* file status of RCS and work file   */
  1468. Xextern int  haveRCSstat, haveworkstat;/* status indicators                  */
  1469. X
  1470. X
  1471. Xint    copyflag;    /* indicates whether a string should be copied into memory*/
  1472. X
  1473. Xchar * rev, * state, *msg;
  1474. X
  1475. Xint initflag, rcsinitflag;
  1476. Xint lockflag, keepworkingfile,keepflag;
  1477. Xint forceciflag;                      /* forces check in                    */
  1478. Xint symrebindflag; char * symbol;
  1479. Xint textflag; char * textfile;
  1480. Xchar * caller;                        /* caller's login;                    */
  1481. Xchar * author;                        /* alternate author for -w option     */
  1482. Xchar altdate[datelength];             /* alternate date for -d              */
  1483. Xint usestatdate;              /* use mod time of file for -d         */
  1484. Xstruct hshentry * targetdelta;        /* old delta to be generated          */
  1485. Xchar   * olddeltanum;                 /* number of old delta                */
  1486. Xstruct hshentry * gendeltas[hshsize]; /* stores deltas to be generated      */
  1487. Xchar   newdelnum[revlength];          /* holds new revision number          */
  1488. Xint    newdnumlength;                 /* actual length of new rev. num.     */
  1489. Xchar   branchpointnum[revlength];     /* number of branchpoint              */
  1490. Xstruct hshentry newdelta;             /* new delta to be inserted           */
  1491. Xstruct branchhead newbranch;          /* new branch to be inserted          */
  1492. Xchar   logmsg[logsize];               /* buffer for log message             */
  1493. X
  1494. Xmain (argc, argv)
  1495. Xint argc;
  1496. Xchar * argv[];
  1497. X{
  1498. X    char * nametest;
  1499. X        char * cmdusage;         /* holds command format                    */
  1500. X        struct stat filestatus;  /* used for getting the mode               */
  1501. X        int  msglen;             /* length of message given by -m           */
  1502. X    int exit_stats;         /* return code for command invocations     */
  1503. X    int newRCSmode;          /* mode for RCS file                       */
  1504. X    long unixtime;
  1505. X    struct tm  parseddate, *ftm;
  1506. X
  1507. X    catchints();
  1508. X        cmdid = "ci";
  1509. X        cmdusage = "command format:\nci -r[rev] -l[rev] -u[rev] -f[rev] -k[rev] -q[rev] -mmsg -nname -Nname -sstate -t[txtfile] file ...";
  1510. X    rev = state = msg = symbol = textfile = nil;
  1511. X        initflag= rcsinitflag= symrebindflag= textflag= quietflag= false;
  1512. X        forceciflag= lockflag= keepworkingfile= keepflag= false;
  1513. X    caller = getcaller(); author = nil; /* author may be reset by -w */
  1514. X    altdate[0]= '\0'; /* empty alternate date for -d */
  1515. X    usestatdate=false;
  1516. X
  1517. X        while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
  1518. X                switch ((*argv)[1]) {
  1519. X
  1520. X                case 'r':
  1521. X                        lockflag=false;
  1522. X                revno:  if ((*argv)[2]!='\0') {
  1523. X                                if (rev!=nil) warn("Redefinition of revision number");
  1524. X                                rev = (*argv)+2;
  1525. X                        }
  1526. X                        break;
  1527. X
  1528. X                case 'l':
  1529. X                        keepworkingfile=lockflag=true;
  1530. X                        goto revno;
  1531. X
  1532. X                case 'u':
  1533. X                        keepworkingfile=true; lockflag=false;
  1534. X                        goto revno;
  1535. X
  1536. X                case 'q':
  1537. X                        quietflag=true;
  1538. X                        goto revno;
  1539. X
  1540. X                case 'f':
  1541. X                        forceciflag=true;
  1542. X                        goto revno;
  1543. X
  1544. X                case 'k':
  1545. X                        keepflag=true;
  1546. X                        goto revno;
  1547. X
  1548. X                case 'm':
  1549. X                        if ((*argv)[2]!='\0'){
  1550. X                                if (msg!=nil)warn("Redefinition of -m option");
  1551. X                                msg = (*argv)+2;
  1552. X                                msglen=strlen(msg);
  1553. X                                if (msglen >= logsize) {
  1554. X                                   warn("log message truncated to %d characters",
  1555. X                                        logsize);
  1556. X                                   msg[logsize-2]='\n';
  1557. X                                   msg[logsize-1]='\0';
  1558. X                                }
  1559. X                                if (msg[msglen-1]!='\n') {
  1560. X                                   /*append linefeed*/
  1561. X                                   VOID strcpy(logmsg,msg);msg=logmsg;
  1562. X                                   msg[msglen]  = '\n';
  1563. X                                   msg[++msglen]= '\0';
  1564. X                                }
  1565. X                        } else warn("Missing message for -m option");
  1566. X                        break;
  1567. X
  1568. X                case 'n':
  1569. X                        symrebindflag=false;
  1570. X                        if ((*argv)[2]!='\0'){
  1571. X                                if (symbol!=nil)warn("Redefinition of symbolic name");
  1572. X                                symbol = (*argv)+2;
  1573. X                if (!(nametest=checkid(symbol,' '))||*nametest)
  1574. X                    faterror("Name %s must be one word",symbol);
  1575. X                        } else warn("Missing name for -n option");
  1576. X                        break;
  1577. X
  1578. X                case 'N':
  1579. X                        symrebindflag=true;
  1580. X                        if ((*argv)[2]!='\0'){
  1581. X                                if (symbol!=nil)warn("Redefinition of symbolic name");
  1582. X                                symbol = (*argv)+2;
  1583. X                if (!(nametest=checkid(symbol,' '))||*nametest)
  1584. X                    faterror("Name %s must be one word",symbol);
  1585. X                        } else warn("Missing name for -N option");
  1586. X                        break;
  1587. X
  1588. X                case 's':
  1589. X                        if ((*argv)[2]!='\0'){
  1590. X                                if (state!=nil)warn("Redefinition of -s option");
  1591. X                                state = (*argv)+2;
  1592. X                                VOID checkid(state,' ');
  1593. X                        } else warn("Missing state for -s option");
  1594. X                        break;
  1595. X
  1596. X                case 't':
  1597. X                        textflag=true;
  1598. X                        if ((*argv)[2]!='\0'){
  1599. X                                if (textfile!=nil)warn("Redefinition of -t option");
  1600. X                                textfile = (*argv)+2;
  1601. X                        }
  1602. X                        break;
  1603. X
  1604. X        case 'd':
  1605. X                        if ((*argv)[2]!='\0'){
  1606. X                if (altdate[0]!='\0' || usestatdate==true)
  1607. X                    warn("Redefinition of -d option");
  1608. X                /* process the date */
  1609. X                if ( partime((*argv)+2, &parseddate) == 0) {
  1610. X                    faterror("Can't parse date/time: %s", (*argv)+2);
  1611. X                    break;
  1612. X                }
  1613. X                if ( (unixtime = maketime(&parseddate)) == 0L) {
  1614. X                    faterror("Inconsistent date/time: %s",(*argv)+2);
  1615. X                    break;
  1616. X                }
  1617. X                ftm = localtime(&unixtime);
  1618. X                VOID sprintf(altdate,DATEFORM,
  1619. X                ftm->tm_year,ftm->tm_mon+1,ftm->tm_mday,ftm->tm_hour,ftm->tm_min,ftm->tm_sec);
  1620. X            } else 
  1621. X                usestatdate++;
  1622. X                        break;
  1623. X
  1624. X        case 'w':
  1625. X                        if ((*argv)[2]!='\0'){
  1626. X                if (author!=nil)warn("Redefinition of -w option");
  1627. X                author = (*argv)+2;
  1628. X                VOID checkid(author,' ');
  1629. X            } else warn("Missing author for -w option");
  1630. X                        break;
  1631. X
  1632. X
  1633. X
  1634. X
  1635. X                default:
  1636. X                        faterror("unknown option: %s\n%s", *argv,cmdusage);
  1637. X                };
  1638. X        }  /* end processing of options */
  1639. X
  1640. X        if (argc<1) faterror("No input file\n%s",cmdusage);
  1641. X
  1642. X        if (!ttystdin() && msg==nil && textflag && textfile==nil) {
  1643. X                /* would need both log message and descriptive text from a file */
  1644. X                faterror("Can't take both log and description from redirected stdin; use -ttextfile");
  1645. X        }
  1646. X        /* now handle all filenames */
  1647. X        do {
  1648. X        gendeltas[0] = nil;
  1649. X        copyflag=rewriteflag=false;
  1650. X        finptr=frewrite=NULL;
  1651. X        targetdelta=nil;
  1652. X        olddeltanum=nil;
  1653. X
  1654. X        switch (pairfilenames(argc,argv,false,false)) {
  1655. X
  1656. X        case -1:                /* New RCS file */
  1657. X                initflag=true; rcsinitflag=false;
  1658. X                break;
  1659. X
  1660. X        case 0:                 /* Error */
  1661. X                continue;
  1662. X
  1663. X        case 1:                 /* Normal checkin with prev . RCS file */
  1664. X                initflag=false; rcsinitflag=(Head==nil);
  1665. X        }
  1666. X
  1667. X        /* now RCSfilename contains the name of the RCS file, and
  1668. X         * workfilename contains the name of the working file.
  1669. X         * if !initflag, finptr contains the file descriptor for the
  1670. X         * RCS file. The admin node is initialized.
  1671. X         * workstat and RCSstat are set.
  1672. X         */
  1673. X
  1674. X        diagnose("%s  <--  %s", RCSfilename,workfilename);
  1675. X
  1676. X        if (access(workfilename,4)!=0) {
  1677. X                error("working file %s not readable or nonexistent",
  1678. X                       workfilename);
  1679. X                continue;
  1680. X        }
  1681. X
  1682. X        /*
  1683. X         * make sure workfile is a regular file.
  1684. X         */
  1685. X        VOID stat(workfilename, &filestatus);
  1686. X        if ((filestatus.st_mode & S_IFMT) != S_IFREG) {
  1687. X                error("working file %s isn't a regular file", workfilename);
  1688. X                continue;
  1689. X        }
  1690. X
  1691. X        /*
  1692. X         * if RCSfile doesn't exist, use mode from workfile, otherwise
  1693. X         * keep the one from the RCSfile.
  1694. X         */
  1695. X        if (! (initflag || rcsinitflag))
  1696. X            VOID fstat(fileno(finptr), &filestatus);
  1697. X
  1698. X        if (!trydiraccess(RCSfilename)) continue; /* give up */
  1699. X        if (!initflag && !checkaccesslist(caller))   continue; /* give up */
  1700. X        if (!trysema(RCSfilename,true)) continue; /* give up */
  1701. X
  1702. X        if (keepflag) {
  1703. X                /* get keyword values from working file */
  1704. X                if (!getoldkeys(workfilename)) continue;
  1705. X                if (rev==nil && *(rev=prevrev)=='\0') {
  1706. X                        error("Can't find a revision number in %s",workfilename);
  1707. X                        continue;
  1708. X                }
  1709. X        if (*prevdate=='\0' && *altdate=='\0' && usestatdate==false)
  1710. X            warn("Can't find a date in %s",workfilename);
  1711. X        if (*prevauthor=='\0' && author==nil)
  1712. X                        warn("Can't find an author in %s", workfilename);
  1713. X        if (*prevstate=='\0' && state==nil)
  1714. X                        warn("Can't find a state in %s", workfilename);
  1715. X        } /* end processing keepflag */
  1716. X
  1717. X        gettree(); /* reads in the delta tree.*/
  1718. X
  1719. X        /* expand symbolic revision number */
  1720. X        if (!expandsym(rev,newdelnum)) continue;
  1721. X
  1722. X        /* splice new delta into tree */
  1723. X        if (!addelta()) continue;
  1724. X
  1725. X        if (initflag||rcsinitflag) {
  1726. X                diagnose("initial revision: %s",newdelnum);
  1727. X        } else  diagnose("new revision: %s; previous revision: %s",
  1728. X                newdelnum,olddeltanum);
  1729. X
  1730. X        newdelta.num=newdelnum;
  1731. X        newdelta.branches=nil;
  1732. X        newdelta.log=nil;
  1733. X        newdelta.lockedby=nil; /*might be changed by addlock() */
  1734. X    /* set author */
  1735. X    if (author!=nil)
  1736. X        newdelta.author=author;     /* set author given by -w         */
  1737. X    elsif (keepflag && *prevauthor!='\0')
  1738. X        newdelta.author=prevauthor; /* preserve old author of possible*/
  1739. X    else    newdelta.author=caller;     /* otherwise use caller's id      */
  1740. X    if (state!=nil)
  1741. X        newdelta.state=state;       /* set state given by -s          */
  1742. X    elsif (keepflag && *prevstate!='\0')
  1743. X        newdelta.state=prevstate;   /* preserve old state if possilbe */
  1744. X    else    newdelta.state=DEFAULTSTATE;/* otherwise use default state    */
  1745. X    if (usestatdate==true) {
  1746. X        if(haveworkstat<0) {
  1747. X        error("can't stat %s",workfilename);
  1748. X        continue;
  1749. X        } 
  1750. X        ftm = localtime(&workstat.st_mtime);
  1751. X        VOID sprintf(altdate,DATEFORM,ftm->tm_year,ftm->tm_mon+1,
  1752. X        ftm->tm_mday,ftm->tm_hour,ftm->tm_min,ftm->tm_sec);
  1753. X    }
  1754. X    if (*altdate!='\0')
  1755. X        newdelta.date=altdate;      /* set date given by -d           */
  1756. X    elsif (keepflag && *prevdate!='\0') /* preserve old date if possible  */
  1757. X                newdelta.date  =prevdate;
  1758. X    else
  1759. X        newdelta.date = getdate();  /* use current date               */
  1760. X    /* now check validity of date -- needed because of -d and -k          */
  1761. X    if (targetdelta!=nil &&
  1762. X        cmpnum(newdelta.date,targetdelta->date)<=0) {
  1763. X        error("Date %s is not later than %s in existing revision %s",
  1764. X               newdelta.date,targetdelta->date, targetdelta->num);
  1765. X        continue;
  1766. X    }
  1767. X
  1768. X
  1769. X        if (lockflag && !addlock(&newdelta,caller)) continue;
  1770. X        if (symbol && !addsymbol(&newdelta,symbol,symrebindflag)) continue;
  1771. X
  1772. X        /* prepare for rewriting the RCS file */
  1773. X        newRCSfilename=mktempfile(RCSfilename,NEWRCSFILE);
  1774. X        if ((frewrite=fopen(newRCSfilename, "w"))==NULL) {
  1775. X                error("Can't open file %s",newRCSfilename);
  1776. X                continue;
  1777. X        }
  1778. X        putadmin(frewrite);
  1779. X        puttree(Head,frewrite);
  1780. X        putdesc(initflag,textflag,textfile,quietflag);
  1781. X
  1782. X
  1783. X        /* build rest of file */
  1784. X        if (initflag||rcsinitflag) {
  1785. X                /* get logmessage */
  1786. X                newdelta.log=getlogmsg();
  1787. X                if(!putdtext(newdelnum,newdelta.log,workfilename,frewrite)) continue;
  1788. X                ffclose(frewrite); frewrite=NULL;
  1789. X        } else {
  1790. X                diffilename=mktempfile("/tmp/",DIFFILE);
  1791. X                if (&newdelta==Head) {
  1792. X                        /* prepend new one */
  1793. X                        rewriteflag=false;
  1794. X                        if (!(expfilename=
  1795. X                              buildrevision(gendeltas,targetdelta,"/tmp/",false))) continue;
  1796. X                        if (!mustcheckin(expfilename,targetdelta)) continue;
  1797. X                                /* don't check in files that aren't different, unless forced*/
  1798. X                        newdelta.log=getlogmsg();
  1799. X                        exit_stats = run((char*)nil, diffilename,
  1800. X                DIFF,"-n",workfilename,expfilename, (char*)nil);
  1801. X                        if (exit_stats != 0 && exit_stats != (1 << BYTESIZ))
  1802. X                            faterror ("diff failed");
  1803. X                        /* diff returns 2 in the upper byte on failure */
  1804. X                        if(!putdtext(newdelnum,newdelta.log,workfilename,frewrite)) continue;
  1805. X                        if(!putdtext(olddeltanum,targetdelta->log,diffilename,frewrite)) continue;
  1806. X                } else {
  1807. X                        /* insert new delta text */
  1808. X                        rewriteflag=true;
  1809. X                        if (!(expfilename=
  1810. X                              buildrevision(gendeltas,targetdelta,"/tmp/",false))) continue;
  1811. X                        if (!mustcheckin(expfilename,targetdelta)) continue;
  1812. X                                /* don't check in files that aren't different, unless forced*/
  1813. X                        newdelta.log=getlogmsg();
  1814. X                        exit_stats = run((char*)nil, diffilename,
  1815. X                DIFF,"-n",expfilename,workfilename, (char*)nil);
  1816. X                        if (exit_stats != 0 && exit_stats != (1 << BYTESIZ))
  1817. X                            faterror ("diff failed");
  1818. X                        if(!putdtext(newdelnum,newdelta.log,diffilename,frewrite)) continue;
  1819. X                }
  1820. X
  1821. X                /* rewrite rest of RCS file */
  1822. X                fastcopy(finptr,frewrite);
  1823. X                ffclose(frewrite); frewrite=NULL;
  1824. X        }
  1825. X    ignoreints();
  1826. X        if (rename(newRCSfilename,RCSfilename)<0) {
  1827. X                error("Can't write new RCS file %s; saved in %s",
  1828. X                      RCSfilename,newRCSfilename);
  1829. X                newRCSfilename[0]='\0'; /* avoid deletion by cleanup*/
  1830. X                restoreints();
  1831. X                VOID cleanup();
  1832. X                break;
  1833. X        }
  1834. X        newRCSfilename[0]='\0'; /* avoid re-unlinking by cleanup()*/
  1835. X
  1836. X    newRCSmode= (initflag|rcsinitflag?workstat.st_mode:RCSstat.st_mode)& ~0222;
  1837. X    /* newRCSmode is also used to adjust mode of working file for -u and -l */
  1838. X    if (chmod(RCSfilename,newRCSmode)<0)
  1839. X                warn("Can't set mode of %s",RCSfilename);
  1840. X
  1841. X        restoreints();
  1842. X#       ifdef SNOOPFILE
  1843. X        logcommand("ci",&newdelta,gendeltas,caller);
  1844. X#       endif
  1845. X
  1846. X        if (!keepworkingfile) {
  1847. X                VOID unlink(workfilename); /* get rid of old file */
  1848. X        } else {
  1849. X                /* expand keywords in file */
  1850. X                newworkfilename=
  1851. X                xpandfile(workfilename,workfilename /*for directory*/,&newdelta);
  1852. X                if (!newworkfilename) continue; /* expand failed */
  1853. X        ignoreints();
  1854. X        if (rename(newworkfilename,workfilename) <0) {
  1855. X                    error("Can't expand keywords in %s",workfilename);
  1856. X                    restoreints();
  1857. X                    continue;
  1858. X                }
  1859. X        newworkfilename[0]='\0'; /* avoid re-unlink by cleanup */
  1860. X        if (chmod(workfilename, WORKMODE(newRCSmode))<0)
  1861. X                    warn("Can't adjust mode of %s",workfilename);
  1862. X                restoreints();
  1863. X        }
  1864. X        diagnose("done");
  1865. X
  1866. X        } while (cleanup(),
  1867. X                 ++argv, --argc >=1);
  1868. X
  1869. X        exit(nerror!=0);
  1870. X    /*NOTREACHED*/
  1871. X}       /* end of main (ci) */
  1872. X/*****************************************************************/
  1873. X/* the rest are auxiliary routines                               */
  1874. X
  1875. X
  1876. Xint addelta()
  1877. X/* Function: Appends a delta to the delta tree, whose number is
  1878. X * given by newdelnum[]. Updates Head, newdelnum, newdenumlength,
  1879. X * olddeltanum and the links in newdelta.
  1880. X * Retruns false on error, true on success.
  1881. X */
  1882. X{
  1883. X        register char * sp, * tp;
  1884. X        register int i;
  1885. X
  1886. X        newdnumlength=countnumflds(newdelnum);
  1887. X
  1888. X        if (initflag || rcsinitflag ) {
  1889. X                /* this covers non-existing RCS file and a file initialized with rcs -i */
  1890. X        if ((newdnumlength==0)&&(Dbranch!=nil)) {
  1891. X            VOID strcpy(newdelnum,Dbranch->num);
  1892. X            newdnumlength=countnumflds(newdelnum);
  1893. X        }
  1894. X                if (newdnumlength==0) VOID strcpy(newdelnum,"1.1");
  1895. X                elsif (newdnumlength==1) VOID strcat(newdelnum,".1");
  1896. X                elsif (newdnumlength>2) {
  1897. X                    error("Branch point does not exist for %s",newdelnum);
  1898. X                    return false;
  1899. X                } /* newdnumlength == 2 is OK;  */
  1900. X                olddeltanum=nil;
  1901. X                Head = &newdelta;
  1902. X                newdelta.next=nil;
  1903. X                return true;
  1904. X        }
  1905. X        if (newdnumlength==0) {
  1906. X                /* derive new revision number from locks */
  1907. X        targetdelta=findlock(caller,true); /*find and delete it*/
  1908. X                if (targetdelta) {
  1909. X                    /* found an old lock */
  1910. X                    olddeltanum=targetdelta->num;
  1911. X                    /* check whether locked revision exists */
  1912. X                    if (!genrevs(olddeltanum,(char *)nil,(char *)nil,(char *)nil,gendeltas)) return false;
  1913. X                    if (targetdelta==Head) {
  1914. X                        /* make new head */
  1915. X                        newdelta.next=Head;
  1916. X                        Head= &newdelta;
  1917. X                        incnum(olddeltanum, newdelnum);
  1918. X                    } elsif ((targetdelta->next==nil)&&(countnumflds(olddeltanum)>2)) {
  1919. X                        /* new tip revision on side branch */
  1920. X                        targetdelta->next= &newdelta;
  1921. X                        newdelta.next = nil;
  1922. X                        incnum(olddeltanum, newdelnum);
  1923. X                    } else {
  1924. X                        /* middle revision; start a new branch */
  1925. X                        newdelnum[0]='\0';
  1926. X                        if (!addbranch(targetdelta,newdelnum)) return false;
  1927. X                    }
  1928. X                    return true; /* successfull use of existing lock */
  1929. X                } else {
  1930. X                    /* no existing lock; try Dbranch */
  1931. X                    /* update newdelnum */
  1932. X                    if (!((StrictLocks==false) && (getuid() == RCSstat.st_uid))) {
  1933. X                        error("no lock set by %s",caller);
  1934. X                        return false;
  1935. X                    }
  1936. X                    if (Dbranch) {
  1937. X                        VOID strcpy(newdelnum,Dbranch->num);
  1938. X                    } else {
  1939. X                        incnum(Head->num,newdelnum);
  1940. X                    }
  1941. X                    newdnumlength=countnumflds(newdelnum);
  1942. X                    /* now fall into next statement */
  1943. X                }
  1944. X        }
  1945. X        if (newdnumlength<=2) {
  1946. X                /* add new head per given number */
  1947. X                olddeltanum=Head->num;
  1948. X                if(newdnumlength==1) {
  1949. X                    /* make a two-field number out of it*/
  1950. X                    if (cmpnumfld(newdelnum,olddeltanum,1)==0)
  1951. X                          incnum(olddeltanum,newdelnum);
  1952. X                    else  VOID strcat(newdelnum, ".1");
  1953. X                }
  1954. X                if (cmpnum(newdelnum,olddeltanum) <= 0) {
  1955. X                    error("deltanumber %s too low; must be higher than %s",
  1956. X                          newdelnum,Head->num);
  1957. X                    return false;
  1958. X                }
  1959. X                if (!(targetdelta=removelock(caller,Head))) return false;
  1960. X                if (!(genrevs(olddeltanum,(char *)nil,(char *)nil,(char *)nil,gendeltas))) return false;
  1961. X                newdelta.next=Head;
  1962. X                Head= &newdelta;
  1963. X        } else {
  1964. X                /* put new revision on side branch */
  1965. X                /*first, get branch point */
  1966. X                tp=branchpointnum; sp=newdelnum;
  1967. X                for(i=newdnumlength-(newdnumlength%2==1?1:2);i>0;i--) {
  1968. X                    while (*sp != '.') *tp++ = *sp++; /*copy field*/
  1969. X                    *tp++ = *sp++;                    /*copy dot  */
  1970. X                }
  1971. X                *(tp-1) = '\0'; /* kill final dot */
  1972. X                olddeltanum=branchpointnum; /*temporary old delta*/
  1973. X                if (!(targetdelta=genrevs(branchpointnum,(char *)nil,(char *)nil,(char *)nil,gendeltas)))
  1974. X                     return false;
  1975. X                if (cmpnum(targetdelta->num,branchpointnum)!=0) {
  1976. X                    error("Cannot find branchpoint %s",branchpointnum);
  1977. X                    return false;
  1978. X                }
  1979. X                if (!addbranch(targetdelta,newdelnum)) return false;
  1980. X        }
  1981. X        return true;
  1982. X}
  1983. X
  1984. X
  1985. X
  1986. Xint addbranch(branchpoint,num)
  1987. Xstruct hshentry * branchpoint;
  1988. Xchar * num;
  1989. X/* adds a new branch and branch delta at branchpoint.
  1990. X * If num is the null string, appends the new branch, incrementing
  1991. X * the highest branch number (initially 1), and setting the level number to 1.
  1992. X * the new delta and branchhead are in globals newdelta and newbranch, resp.
  1993. X * the new number is placed into num.
  1994. X * returns false on error.
  1995. X */
  1996. X{
  1997. X        struct branchhead * bhead, * btrail;
  1998. X        char branchnum[revlength];
  1999. X        int numlength, result, field;
  2000. X
  2001. X        numlength = countnumflds(num);
  2002. X
  2003. X        if (branchpoint->branches==nil) {
  2004. X                /* start first branch */
  2005. X                branchpoint->branches = &newbranch;
  2006. X                if (numlength==0) {
  2007. X                        VOID strcpy(num, branchpoint->num);
  2008. X                        VOID strcat(num,".1.1");
  2009. X                } elsif(countnumflds(num)%2 == 1)
  2010. X                        VOID strcat(num, ".1");
  2011. X                newbranch.nextbranch=nil;
  2012. X
  2013. X        } elsif (numlength==0) {
  2014. X                /* append new branch to the end */
  2015. X                bhead=branchpoint->branches;
  2016. X                while (bhead->nextbranch) bhead=bhead->nextbranch;
  2017. X                bhead->nextbranch = &newbranch;
  2018. X                getbranchno(bhead->hsh->num,branchnum);
  2019. X                incnum(branchnum,num);
  2020. X                VOID strcat(num,".1");
  2021. X                newbranch.nextbranch=nil;
  2022. X        } else {
  2023. X                /* place the branch properly */
  2024. X                field = numlength - (numlength%2 ==1?0:1);
  2025. X                /* field of branch number */
  2026. X                bhead=branchpoint->branches;
  2027. X                while ((bhead!=nil) &&
  2028. X                       ((result=cmpnumfld(num,bhead->hsh->num,field))>0)) {
  2029. X                        btrail=bhead;
  2030. X                        bhead=bhead->nextbranch;
  2031. X                }
  2032. X                if (bhead==nil || result<0) {
  2033. X                        /* insert/append new branchhead */
  2034. X                        if (bhead==branchpoint->branches)
  2035. X                                branchpoint->branches= &newbranch;
  2036. X                        else    btrail->nextbranch= &newbranch;
  2037. X                        newbranch.nextbranch=bhead;
  2038. X                        if (numlength%2 ==1) VOID strcat(num,".1");
  2039. X                } else {
  2040. X                        /* branch exists; append to end */
  2041. X                        getbranchno(num,branchnum);
  2042. X                        if (!(targetdelta=genrevs(branchnum,(char *)nil,(char *)nil,(char *)nil,
  2043. X                                gendeltas))) return false;
  2044. X                        olddeltanum=targetdelta->num;
  2045. X                        if (cmpnum(num,olddeltanum) <= 0) {
  2046. X                                error("deltanumber %s too low; must be higher than %s",
  2047. X                                      num,olddeltanum);
  2048. X                                return false;
  2049. X                        }
  2050. X                        if (!removelock(caller,targetdelta)) return false;
  2051. X                        if (numlength%2==1) incnum(olddeltanum,num);
  2052. X                        targetdelta->next= &newdelta;
  2053. X                        newdelta.next=nil;
  2054. X                        return true; /* Don't do anything to newbranch */
  2055. X                }
  2056. X        }
  2057. X        newbranch.hsh = &newdelta;
  2058. X        newdelta.next=nil;
  2059. X        return true;
  2060. X}
  2061. X
  2062. X
  2063. X
  2064. Xstruct hshentry * removelock(who,delta)
  2065. Xchar * who; struct hshentry * delta;
  2066. X/* function: Finds the lock held by who on delta,
  2067. X * removes it, and returns a pointer to the delta.
  2068. X * Prints an error message and returns nil if there is no such lock.
  2069. X * An exception is if StrictLocks==false, and who is the owner of
  2070. X * the RCS file. If who does not have a lock in this case,
  2071. X * delta is returned.
  2072. X */
  2073. X{
  2074. X        register struct lock * next, * trail;
  2075. X        char * num;
  2076. X        struct lock dummy;
  2077. X        int whomatch, nummatch;
  2078. X
  2079. X        num=delta->num;
  2080. X        dummy.nextlock=next=Locks;
  2081. X        trail = &dummy;
  2082. X        while (next!=nil) {
  2083. X                whomatch=strcmp(who,next->login);
  2084. X                nummatch=strcmp(num,next->delta->num);
  2085. X                if ((whomatch==0) && (nummatch==0)) break;
  2086. X                     /*found a lock on delta by who*/
  2087. X                if ((whomatch!=0)&&(nummatch==0)) {
  2088. X                    error("revision %s locked by %s",num,next->login);
  2089. X                    return nil;
  2090. X                }
  2091. X                trail=next;
  2092. X                next=next->nextlock;
  2093. X        }
  2094. X        if (next!=nil) {
  2095. X                /*found one; delete it */
  2096. X                trail->nextlock=next->nextlock;
  2097. X                Locks=dummy.nextlock;
  2098. X                next->delta->lockedby=nil; /* reset locked-by */
  2099. X                return next->delta;
  2100. X        } else {
  2101. X                if (!((StrictLocks==false) && (getuid() == RCSstat.st_uid))) {
  2102. X                    error("no lock set by %s for revision %s",who,num);
  2103. X                    return nil;
  2104. X                } else {
  2105. X                        return delta;
  2106. X                }
  2107. X        }
  2108. X}
  2109. X
  2110. X
  2111. X
  2112. Xchar * getdate()
  2113. X/* Function: returns a pointer to the current date in the form
  2114. X * YY.MM.DD.hh.mm.ss\0
  2115. X */
  2116. X{
  2117. X        long clock;
  2118. X        struct tm * tm;
  2119. X    static char buffer[datelength]; /* date buffer */
  2120. X        clock=time((long *)0);
  2121. X        tm=localtime(&clock);
  2122. X        VOID sprintf(buffer, DATEFORM,
  2123. X                tm->tm_year, tm->tm_mon+1, tm->tm_mday,
  2124. X                tm->tm_hour, tm->tm_min, tm->tm_sec);
  2125. X        return buffer;
  2126. X}
  2127. X
  2128. X
  2129. Xchar * xpandfile (unexfname,dir,delta)
  2130. Xchar * unexfname, * dir;
  2131. Xstruct hshentry * delta;
  2132. X/* Function: Reads file unexpfname and copies it to a
  2133. X * file in dir, performing keyword substitution with data from delta.
  2134. X * returns the name of the expanded file if successful, nil otherwise.
  2135. X */
  2136. X{       char * targetfname;
  2137. X        FILE * unexfile, *exfile;
  2138. X
  2139. X        targetfname=mktempfile(dir,TMPFILE3);
  2140. X        if ((unexfile=fopen(unexfname,  "r" ))==NULL ||
  2141. X            (exfile  =fopen(targetfname,"w"))==NULL) {
  2142. X                error("Can't expand file %s",unexfname);
  2143. X                return nil;
  2144. X        }
  2145. X        while (expandline(unexfile,exfile,delta,false,false)); /*expand*/
  2146. X        ffclose(unexfile);ffclose(exfile);
  2147. X        return targetfname;
  2148. X}
  2149. X
  2150. X
  2151. Xmustcheckin (unexfname,delta)
  2152. Xchar * unexfname; struct hshentry * delta;
  2153. X/* Function: determines whether checkin should proceed.
  2154. X * Compares the wrkfilename with unexfname, disregarding keywords.
  2155. X * If the 2 files differ, returns true. If they do not differ, asks the user
  2156. X * whether to return true or false (i.e., whether to checkin the file anyway.
  2157. X * If the files do not differ, and quietflag==true, returns false.
  2158. X * Shortcut: If forceciflag==true, mustcheckin() always returns true.
  2159. X */
  2160. X{       register int c;
  2161. X        int response, result;
  2162. X
  2163. X        if (forceciflag) return true;
  2164. X
  2165. X        if (!rcsfcmp(workfilename,unexfname,delta)) return true;
  2166. X        /* If files are different, must check them in. */
  2167. X
  2168. X        /* files are the same */
  2169. X        diagnose("File %s is unchanged with respect to revision %s",
  2170. X                workfilename,delta->num);
  2171. X        if (quietflag || !ttystdin()) {
  2172. X                /* Files are the same, but can't ask, so don't checkin*/
  2173. X                result=false;
  2174. X        } else {
  2175. X                /* ask user whether to check in */
  2176. X                VOID fputs("checkin anyway? [ny](n): ",stderr);
  2177. X                response=c=getchar();
  2178. X                while (!(c==EOF || c=='\n')) c=getchar();/*skip to end of line*/
  2179. X                result=(response=='y'||response=='Y');
  2180. X        }
  2181. X        if (result==false) {
  2182. X                if (quietflag) {
  2183. X                    warn("checkin aborted since %s was not changed; %s %sdeleted.",
  2184. X                             workfilename,workfilename,keepworkingfile?"not ":"");
  2185. X                } else {
  2186. X                    diagnose("checkin aborted; %s %sdeleted.",
  2187. X                             workfilename,keepworkingfile?"not ":"");
  2188. X                }
  2189. X                if (!keepworkingfile) VOID unlink(workfilename);
  2190. X        }
  2191. X        return result;
  2192. X}
  2193. X
  2194. X
  2195. X
  2196. X
  2197. X/* --------------------- G E T L O G M S G --------------------------------*/
  2198. Xextern int stdinread; /* is >0 if redirected stdin has been read once.     */
  2199. X
  2200. X
  2201. Xchar * getlogmsg()
  2202. X/* Function: obtains a log message and returns a pointer to it.
  2203. X * If a log message is given via the -m option, a pointer to that
  2204. X * string is returned.
  2205. X * If this is the initial revision, a standard log message is returned.
  2206. X * Otherwise, reads a character string from the terminal.
  2207. X * The string must be terminated with a control-d or a single '.' on a
  2208. X * line. getlogmsg prompts the first time it is called for the
  2209. X * log message; during all later calls it asks whether the previous
  2210. X * log message can be reused.
  2211. X * returns a pointer to the character string; the pointer is always non-nil.
  2212. X */
  2213. X{
  2214. X        static logyet;      /*indicates whether previous log present*/
  2215. X        static char emptylog[]  = "*** empty log message ***\n";
  2216. X        static char initiallog[]= "Initial revision\n";
  2217. X        char response;
  2218. X    int cin;
  2219. X        register char c, old1, old2, * tp;
  2220. X
  2221. X        if (msg) return msg;
  2222. X
  2223. X        if ((olddeltanum==nil)&&
  2224. X        ((cmpnum(newdelnum,"1.1")==0)||(cmpnum(newdelnum,"1.0")==0))) {
  2225. X                return initiallog;
  2226. X    }
  2227. X    if (keepflag) {
  2228. X        /* generate std. log message */
  2229. X        VOID sprintf(logmsg, "checked in with -k by %s at %s.\n",caller,getdate());
  2230. X        return(logmsg);
  2231. X    }
  2232. X        if (logyet) {
  2233. X                /*previous log available*/
  2234. X                if (!ttystdin()) return logmsg; /* reuse if stdin is not a terminal*/
  2235. X                /* otherwise ask */
  2236. X        clearerr(stdin);        /* reset EOF ptr */
  2237. X        VOID fputs("reuse log message of previous file? [yn](y): ",stderr);
  2238. X                cin=getchar();
  2239. X        response=cin;
  2240. X                while (!(cin==EOF || cin=='\n')) cin=getchar();/*skip to end of line*/
  2241. X                if (response=='\n'||response=='y'||response=='Y')
  2242. X                        return logmsg;
  2243. X                else
  2244. X                        logmsg[0]='\0'; /*kill existing log message */
  2245. X        }
  2246. X
  2247. X        /* now read string from stdin */
  2248. X        if (ttystdin()) {
  2249. X                VOID fputs("enter log message:\n(terminate with ^D or single '.')\n>> ",stderr);
  2250. X        } else {  /* redirected stdin */
  2251. X                if (stdinread>0)
  2252. X                    faterror("Can't reread redirected stdin for log message; use -m");
  2253. X                stdinread++;
  2254. X        }
  2255. X
  2256. X    tp=logmsg; old1='\n'; old2=' ';
  2257. X    if (feof(stdin))
  2258. X        clearerr(stdin);
  2259. X        for (;;) {
  2260. X                cin=getchar();
  2261. X                if (cin==EOF) {
  2262. X            if(ttystdin()) {
  2263. X                VOID printf("\n");
  2264. X                clearerr(stdin);
  2265. X            }
  2266. X            if ((tp==logmsg)||(*(tp-1)!='\n')) *tp++ = '\n'; /* append newline */
  2267. X                        *tp = '\0'; /*terminate*/
  2268. X                        break;
  2269. X                }
  2270. X                if (cin=='\n' && old1=='.' && old2=='\n') {
  2271. X                        *(tp-1) = '\0'; /*kill last period */
  2272. X                        break;
  2273. X                }
  2274. X                if (tp>=logmsg+logsize-2) { /* overflow */
  2275. X                        if (!ttystdin()) {
  2276. X                                warn("log message truncated to %d characters",logsize);
  2277. X                                logmsg[logsize-2]='\n';logmsg[logsize-1]='\0';
  2278. X                                return logmsg;
  2279. X                        }
  2280. X                        VOID fprintf(stderr,"log message too long. Maximum: %d\n",logsize);
  2281. X                        VOID fputs("reenter log message:\n>> ",stderr);
  2282. X                        tp=logmsg; old1='\n'; old2=' ';
  2283. X                        while (cin!='\n') cin=getchar(); /*skip line */
  2284. X                        continue;
  2285. X                }
  2286. X                if (cin=='\n' && ttystdin()) VOID fputs(">> ",stderr);
  2287. X                *tp++ = cin; old2=old1; old1=cin; /* this is the actual work!*/
  2288. X                /*SDELIM will be changed to double SDELIM by putdtext*/
  2289. X        } /* end for */
  2290. X
  2291. X        /* now check whether the log message is not empty */
  2292. X        tp=logmsg;
  2293. X        while ((c= *tp++)==' '||c=='\t'||c=='\n'||c=='\f');
  2294. X        if (*tp=='\0') {
  2295. X                logyet=false;
  2296. X                return emptylog;
  2297. X        } else {
  2298. X                logyet=true;
  2299. X                return logmsg;
  2300. X        }
  2301. X}
  2302. X@
  2303. X
  2304. X
  2305. X4.9.2.1
  2306. Xlog
  2307. X@Start of Amiga RCS port branch.
  2308. X@
  2309. Xtext
  2310. X@d31 1
  2311. Xa31 5
  2312. X<<<<<<< ci.c
  2313. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS.cbmvax/ci.c,v 4.9.1.1 89/08/11 01:41:27 rsbx Exp Locker: rsbx $ Purdue CS";
  2314. X=======
  2315. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 1.2 89/09/17 13:09:11 rick Exp $ Purdue CS";
  2316. X>>>>>>> 1.2
  2317. Xa40 10
  2318. X<<<<<<< ci.c
  2319. X * Revision 4.9.1.1  89/08/11  01:41:27  rsbx
  2320. X * Start of cbmvax RCS source branch.
  2321. X=======
  2322. X * Revision 1.2  89/09/17  13:09:11  rick
  2323. X * Port to AmigaDos done by Rick Schaeffer
  2324. X * All changes done with conditional compile.  This version only compiles
  2325. X * correctly with Lattice C version 5.02 or later.
  2326. X>>>>>>> 1.2
  2327. X * 
  2328. Xa41 3
  2329. X * checked in with -k by rsbx at 89.08.10.16.00.43.
  2330. X * 
  2331. X * Revision 4.9  89/05/01  15:10:54  narten
  2332. Xa143 7
  2333. X#ifdef AMIGA
  2334. X#include "stat.h"
  2335. X#undef WORKMODE
  2336. X#define WORKMODE(RCSmode) (RCSmode | S_IWRITE)&~((lockflag||!StrictLocks)?S_IWRITE:0)
  2337. X#undef putc
  2338. X#define putc(x,y) fputc(x,y)
  2339. X#else
  2340. Xa145 1
  2341. X#endif
  2342. Xa500 3
  2343. X#ifdef AMIGA
  2344. X                diffilename=mktempfile("t:",DIFFILE);
  2345. X#else
  2346. Xa501 1
  2347. X#endif
  2348. Xa505 3
  2349. X#ifdef AMIGA
  2350. X                              buildrevision(gendeltas,targetdelta,"t:",false))) continue;
  2351. X#else
  2352. Xa506 1
  2353. X#endif
  2354. Xa509 1
  2355. X<<<<<<< ci.c
  2356. Xa511 5
  2357. X=======
  2358. X                        VOID sprintf(command,"%s -n %s %s >%s\n", DIFF,
  2359. X                                workfilename,expfilename,diffilename);
  2360. X                        exit_stats = system (command);
  2361. X>>>>>>> 1.2
  2362. Xa520 3
  2363. X#ifdef AMIGA
  2364. X                              buildrevision(gendeltas,targetdelta,"t:",false))) continue;
  2365. X#else
  2366. Xa521 1
  2367. X#endif
  2368. Xa524 1
  2369. X<<<<<<< ci.c
  2370. Xa526 5
  2371. X=======
  2372. X                        VOID sprintf(command,"%s -n %s %s >%s\n", DIFF,
  2373. X                                expfilename,workfilename,diffilename);
  2374. X                        exit_stats = system (command);
  2375. X>>>>>>> 1.2
  2376. Xa536 4
  2377. X#ifdef AMIGA
  2378. X    fclose(finptr);
  2379. X    unlink(RCSfilename);
  2380. X#endif
  2381. Xd546 1
  2382. Xa546 3
  2383. X#ifdef AMIGA
  2384. X    newRCSmode =(initflag|rcsinitflag?workstat.st_attr:RCSstat.st_attr)|S_IWRITE;
  2385. X#else
  2386. Xa547 1
  2387. X#endif
  2388. Xa564 3
  2389. X#ifdef AMIGA
  2390. X        unlink(workfilename);
  2391. X#endif
  2392. Xa642 3
  2393. X#ifdef AMIGA
  2394. X            if (StrictLocks != false) {
  2395. X#else
  2396. Xa643 1
  2397. X#endif
  2398. Xa811 3
  2399. X#ifdef AMIGA
  2400. X                if (StrictLocks !=false) {
  2401. X#else
  2402. Xa812 1
  2403. X#endif
  2404. Xa887 3
  2405. X#ifdef AMIGA
  2406. X        fflush(stderr);
  2407. X#endif
  2408. Xa948 3
  2409. X#ifdef AMIGA
  2410. X        fflush(stderr);
  2411. X#endif
  2412. Xd961 1
  2413. Xa961 4
  2414. X#ifdef AMIGA
  2415. X        fflush(stderr);
  2416. X#endif
  2417. X           } else {  /* redirected stdin */
  2418. Xa992 3
  2419. X#ifdef AMIGA
  2420. X            fflush(stderr);
  2421. X#endif
  2422. Xa996 1
  2423. X<<<<<<< ci.c
  2424. Xa997 8
  2425. X=======
  2426. X                if (cin=='\n' && isatty(fileno(stdin))) {
  2427. X                     VOID fputs(">> ",stderr);
  2428. X#ifdef AMIGA
  2429. X            fflush(stderr);
  2430. X#endif
  2431. X            }
  2432. X>>>>>>> 1.2
  2433. X@
  2434. X
  2435. X
  2436. X4.9.2.2
  2437. Xlog
  2438. X@Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
  2439. Xsources I have here (and are later than the ones Rick used).
  2440. X@
  2441. Xtext
  2442. X@d31 5
  2443. Xa35 1
  2444. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 4.9.2.1 89/10/13 19:17:07 rsbx Exp Locker: rsbx $ Purdue CS";
  2445. Xd45 1
  2446. Xa45 3
  2447. X * Revision 4.9.2.1  89/10/13  19:17:07  rsbx
  2448. X * Start of Amiga RCS port branch.
  2449. X * 
  2450. Xd48 6
  2451. Xa421 3
  2452. X#ifdef AMIGA
  2453. X    if (filestatus.st_type >= 0) {
  2454. X#else
  2455. Xa422 1
  2456. X#endif
  2457. Xd432 1
  2458. Xa432 1
  2459. X            VOID stat(RCSfilename, &filestatus);
  2460. Xd543 1
  2461. Xd546 5
  2462. Xd568 1
  2463. Xd571 5
  2464. Xd1076 3
  2465. Xd1085 1
  2466. X@
  2467. X
  2468. X
  2469. X4.9.2.3
  2470. Xlog
  2471. X@More changes to make Amiga port work.
  2472. X@
  2473. Xtext
  2474. X@d31 1
  2475. Xa31 1
  2476. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 4.9.2.2 89/10/15 15:40:32 rsbx Exp $ Purdue CS";
  2477. Xa40 4
  2478. X * Revision 4.9.2.2  89/10/15  15:40:32  rsbx
  2479. X * Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
  2480. X * sources I have here (and are later than the ones Rick used).
  2481. X * 
  2482. Xd523 1
  2483. Xa523 1
  2484. X        diffilename=mktempfile("t:",DIFFILE);
  2485. X@
  2486. X
  2487. X
  2488. X4.9.2.4
  2489. Xlog
  2490. X@NULL finptr after closing it.
  2491. X@
  2492. Xtext
  2493. X@d31 1
  2494. Xa31 1
  2495. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 4.9.2.3 89/10/15 18:26:56 rsbx Exp $ Purdue CS";
  2496. Xa40 3
  2497. X * Revision 4.9.2.3  89/10/15  18:26:56  rsbx
  2498. X * More changes to make Amiga port work.
  2499. X * 
  2500. Xd575 1
  2501. Xa575 1
  2502. X    fclose(finptr); finptr = NULL;
  2503. X@
  2504. X
  2505. X
  2506. X4.9.2.5
  2507. Xlog
  2508. X@Changes to make the delete bit to track the write bit. Made protection
  2509. Xbit manipulation less insane.
  2510. X@
  2511. Xtext
  2512. X@d31 1
  2513. Xa31 1
  2514. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 4.9.2.4 89/10/30 13:36:06 rsbx Exp $ Purdue CS";
  2515. Xa40 3
  2516. X * Revision 4.9.2.4  89/10/30  13:36:06  rsbx
  2517. X * NULL finptr after closing it.
  2518. X * 
  2519. Xd162 2
  2520. Xd578 2
  2521. Xa579 8
  2522. X    if (finptr) {
  2523. X        fclose(finptr); finptr = NULL;
  2524. X        if (chmod(RCSfilename, RCSstat.st_attr|S_IDELETE)<0)
  2525. X            warn("Can't adjust mode of %s",RCSfilename);
  2526. X        if (unlink(RCSfilename) != 0) {            /* Remove failed   */
  2527. X            error("Can't unlink %s",RCSfilename);
  2528. X            }
  2529. X        }
  2530. Xd591 1
  2531. Xa591 1
  2532. X    newRCSmode =(initflag|rcsinitflag?workstat.st_attr:RCSstat.st_attr)& ~(S_IWRITE|S_IDELETE);
  2533. Xa604 7
  2534. X#ifdef AMIGA
  2535. X        if (chmod(workfilename, workstat.st_attr|S_IDELETE)<0)
  2536. X            warn("Can't adjust mode of %s",workfilename);
  2537. X               if (unlink(workfilename) != 0) {            /* Remove failed   */
  2538. X                   error("Can't unlink %s",workfilename);
  2539. X                   }
  2540. X#else
  2541. Xa605 1
  2542. X#endif
  2543. Xd613 1
  2544. Xa613 5
  2545. X        if (chmod(workfilename, workstat.st_attr|S_IDELETE)<0)
  2546. X            warn("Can't adjust mode of %s",workfilename);
  2547. X               if (unlink(workfilename) != 0) {            /* Remove failed   */
  2548. X                   error("Can't unlink %s",workfilename);
  2549. X                   }
  2550. Xa960 9
  2551. X#ifdef AMIGA
  2552. X        if (!keepworkingfile) {
  2553. X            if (chmod(workfilename, workstat.st_attr|S_IDELETE)<0)
  2554. X                warn("Can't adjust mode of %s",workfilename);
  2555. X            if (unlink(workfilename) != 0) {            /* Remove failed   */
  2556. X                error("Can't unlink %s",workfilename);
  2557. X                }
  2558. X            }
  2559. X#else
  2560. Xa961 1
  2561. X#endif
  2562. X@
  2563. X
  2564. X
  2565. X4.9.2.6
  2566. Xlog
  2567. X@Changed "^D" to "^\".
  2568. X@
  2569. Xtext
  2570. X@d31 1
  2571. Xa31 1
  2572. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 4.9.2.5 89/11/01 14:40:05 rsbx Exp Locker: rsbx $ Purdue CS";
  2573. Xa40 4
  2574. X * Revision 4.9.2.5  89/11/01  14:40:05  rsbx
  2575. X * Changes to make the delete bit to track the write bit. Made protection
  2576. X * bit manipulation less insane.
  2577. X * 
  2578. Xd1053 1
  2579. Xa1054 1
  2580. X                VOID fputs("enter log message:\n(terminate with ^\\ or single '.')\n>> ",stderr);
  2581. Xa1055 2
  2582. X#else
  2583. X                VOID fputs("enter log message:\n(terminate with ^D or single '.')\n>> ",stderr);
  2584. X@
  2585. X
  2586. X
  2587. X4.9.2.7
  2588. Xlog
  2589. X@WaitChild() on the Amiga returns the completion code from a child process
  2590. Xwithout shifting it up 8 bits like the Unix wait() does.
  2591. X@
  2592. Xtext
  2593. X@d31 1
  2594. Xa31 1
  2595. X "$Header: /u/softeng/rsbx/rcs/amiga/RCS/ci.c,v 4.9.2.6 89/11/09 21:28:00 rsbx Exp $ Purdue CS";
  2596. Xa40 3
  2597. X * Revision 4.9.2.6  89/11/09  21:28:00  rsbx
  2598. X * Changed "^D" to "^\".
  2599. X * 
  2600. Xa552 3
  2601. X#ifdef AMIGA
  2602. X                        if (exit_stats != 0 && exit_stats != 1)
  2603. X#else
  2604. Xa553 1
  2605. X#endif
  2606. Xa571 3
  2607. X#ifdef AMIGA
  2608. X                        if (exit_stats != 0 && exit_stats != 1)
  2609. X#else
  2610. Xa572 1
  2611. X#endif
  2612. X@
  2613. X
  2614. X
  2615. X4.9.1.1
  2616. Xlog
  2617. X@Start of cbmvax RCS source branch.
  2618. X@
  2619. Xtext
  2620. X@d31 1
  2621. Xa31 1
  2622. X "$Header: /u/softeng/rsbx/rcs/rcs.uunet/src/RCS/ci.c,v 4.9 89/05/01 15:10:54 narten Exp $ Purdue CS";
  2623. Xa40 3
  2624. X * Revision 4.9  89/05/01  15:10:54  narten
  2625. X * checked in with -k by rsbx at 89.08.10.16.00.43.
  2626. X * 
  2627. X@
  2628. SHAR_EOF
  2629. echo "End of archive 12 (of 14)"
  2630. # if you want to concatenate archives, remove anything after this line
  2631. exit
  2632.